django DRF的增删改查查 您所在的位置:网站首页 play框架的增删改查 django DRF的增删改查查

django DRF的增删改查查

2024-07-07 14:48| 来源: 网络整理| 查看: 265

        使用Django的DRF框架,基于restful接口规范的增删改查(查所有)查(查一个)操作,一般默认有如下规范:

/book/  GET 查看所有资源,返回所有资源; /book/  POST 添加资源,返回添加的资源;

/book/1 GET 查看某一个资源,返回这一个资源;

/book/1 PUT 编辑某一个资源,返回编辑之后的这个资源;

/book/1 DELETE 删除某一个资源,返回空;

一、基于APIView的接口实现

1、urls.py

urlpatterns = [ path('sers/book/', views.BookView.as_view()), re_path('sers/book/(\d+)', views.BookDetailView.as_view()), ]

2、models.py

class Book(models.Model): title = models.CharField(verbose_name="书籍名称",max_length=32) price = models.IntegerField(verbose_name="价格",null=True) #如果不设置null,数据库默认是不能为空的; pub_data = models.DateField(verbose_name="出版时间")

3、views.py

# 针对模型设计序列化器 class BookSerializers(serializers.Serializer): title = serializers.CharField(max_length=32) price = serializers.IntegerField(required=False) pub_data = serializers.DateField() # 字段名要和models中的名字一致,不然会报错,如果需要自定义需要通过如下方法: # data = serializers.DateTimeField(source="pub_data") # seve方法重写 def create(self, validated_data): # 添加数据逻辑 new_book = Book.objects.create(**self.validated_data) return new_book def update(self, instance, validated_data): # 更新逻辑 Book.objects.filter(pk=instance.pk).update(**validated_data) # 针对更新加的两句话,区分instance updated_book = Book.objects.get(pk=instance.pk) return updated_book class BookView(APIView): def get(self,request): '''查看所有书籍''' book_list = models.Book.objects.all() # 构建序列化器对象 serializer = BookSerializers(instance=book_list,many=True) return Response(serializer.data) def post(self,request): '''添加书籍''' # 获取请求数据 data = request.data # 构建序列化器对象 serializer = BookSerializers(data=request.data) # 校验数据:返回布尔值,serializer.validated_data ,在这里校验,如果不通过,保存到这里serializer.errors if serializer.is_valid(): # 数据校验通过,将数据插入到数据库中 # new_book= Book.objects.create(**serializer.validated_data) serializer.save() return Response(serializer.data) else: # 校验失败 return Response(serializer.errors) class BookDetailView(APIView): def get(self,request,id): '''查某一个''' book = Book.objects.get(pk=id) #模型类对象和queryset对象 serializer = BookSerializers(instance=book,many=False) return Response(serializer.data) def put(self,request,id): '''编辑某一个数据,更新数据''' # 找到需要编辑的对象 up_book = Book.objects.get(pk=id) # 构建序列化对象,这里instance和data这两个参数都要有; serializer = BookSerializers(instance=up_book,data=request.data) # 数据校验,反序列化 if serializer.is_valid(): serializer.save() return Response(serializer.data) else: return Response(serializer.errors) def delete(self,request,id): # 删除 Book.objects.get(pk=id).delete() return Response()

4、针对views.py中的模型序列化器,还有以下更简便的写法,这个里面的create和update方法都自动被写好了,不用自己定义,自己只设置字段就可以了。

class BookSerializers(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" # fields = ["title", "price"] # exclude = ["pub_date"] 二、基于GenericAPIView的接口实现 GenericAPIView是继承的APIView,然后又实现了一些自定义的方法。

1、urls.py

path('sers/publish/', views.PublishView.as_view()), # ?p 有名分组,这样写之后会行成 pk=\d 的形式 re_path('sers/publish/(?P\d+)', views.PublishDetailView.as_view()),

2、models.py

class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=32)

3、views.py

from rest_framework.generics import GenericAPIView class PublishSerializers(serializers.ModelSerializer): class Meta: model = Publish fields = "__all__" class PublishView(GenericAPIView): # 定义2个类全局变量;以后复用这个类的时候,只改两个全局变量; queryset = Publish.objects.all() serializer_class = PublishSerializers def get(self,request): '''查看所有''' serializer = self.get_serializer(instance=self.get_queryset(),many=True) return Response(serializer.data) def post(self,request): '''添加''' serializer = self.get_serializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) else: return Response(serializer.errors) class PublishDetailView(GenericAPIView): # 定义2个类全局变量;以后复用这个类的时候,只改两个全局变量; queryset = Publish.objects.all() serializer_class = PublishSerializers def get(self,request,pk): # pk要对应URL中,pk在源码中可以改,不建议改; '''查一个''' serializer = self.get_serializer(instance=self.get_object(), many=False) return Response(serializer.data) def put(self,request,pk): '''编辑''' serializer = self.get_serializer(instance=self.get_object(),data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) else: return Response(serializer.errors) def delete(self,request,pk): '''删除''' self.get_object().delete() return Response() 三、基于Mixin的接口实现 

1、urls.py

path('sers/publish/', views.PublishView.as_view()), # ?p 有名分组,这样写之后会行成 pk=\d 的形式 re_path('sers/publish/(?P\d+)', views.PublishDetailView.as_view()),

2、models.py

class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=32)

3、 views.py

from rest_framework.generics import GenericAPIView from rest_framework.mixins import ListModelMixin,CreateModelMixin,UpdateModelMixin,RetrieveModelMixin,DestroyModelMixin class PublishSerializers(serializers.ModelSerializer): class Meta: model = Publish fields = "__all__" class PublishView(ListModelMixin,CreateModelMixin,GenericAPIView): # 定义2个类全局变量;以后复用这个类的时候,只改两个全局变量; queryset = Publish.objects.all() serializer_class = PublishSerializers def get(self,request): '''查看所有''' # list()方法来源于父类ListModelMixin中的方法 return self.list(request) def post(self,request): '''添加''' # create()方法来源于父类CreateModelMixin中的方法 return self.create(request) class PublishDetailView(RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView): # 定义2个类全局变量;以后复用这个类的时候,只改两个全局变量; queryset = Publish.objects.all() serializer_class = PublishSerializers def get(self,request,pk): '''查一个''' # retrieve()方法来源于父类RetrieveModelMixin中的方法 return self.retrieve(request,pk) def put(self,request,pk): '''编辑''' # update()方法来源于父类UpdateModelMixin中的方法 return self.update(request,pk) def delete(self,request,pk): '''删除''' # destroy()方法来源于父类DestroyModelMixin中的方法 return self.destroy(request,pk)

4、对于views.py中,Mixin类再封装的操作

# ListCreateAPIView 封装了ListModelMixin,CreateModelMixin,GenericAPIView三个类,和get/post两个方法; # RetrieveUpdateDestroyAPIView 封装了RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView四个类,实现了get/put/delete三个方法; from rest_framework.generics import ListCreateAPIView,RetrieveUpdateDestroyAPIView class PublishSerializers(serializers.ModelSerializer): class Meta: model = Publish fields = "__all__" class PublishView(ListCreateAPIView): # get/post方法全部在ListCreateAPIView中,不用自己写; queryset = Publish.objects.all() serializer_class = PublishSerializers # 有的情况下,一个接口不见得会全部要增删改查查,也许只有查看和编辑,不允许删除,还有类可以继承RetrieveUpdateAPIView class PublishDetailView(RetrieveUpdateDestroyAPIView): # get/put/delete方法全部在RetrieveUpdateDestroyAPIView中,不用自己写; queryset = Publish.objects.all() serializer_class = PublishSerializers 四、基于ViewSet的接口实现,涉及到GenericViewSet和ModelViewSet

ViewSet是DRF的一个类,ViewSet继承了ViewSetMixin, views.APIView 由于路由的分发原则是按照请求方式分发的,dispatch里面进行分发; 之前五个方法都是写了2个类,现在要二合一; 必须要修改分发机制,不然五个方法没有办法写在一个类里面; ViewSetMixin重塑了分发机制,不用自己写。

1、urls.py

path('sers/publish/', views.PublishView.as_view({"get":"list","post":"create"})), re_path('sers/publish/(?P\d+)', views.PublishView.as_view({"get":"retrieve","put":"update","delete":"destroy"})),

针对上面的路由写法,也可以通过路由组件完成:

# 路由组件 from rest_framework import routers router=routers.DefaultRouter() router.register("publish",views.PublishView) # 加在最后面,列表外面 urlpatterns += router.urls

2、models.py

class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=32)

3、views.py

第一种方法:

from rest_framework.viewsets import GenericViewSet from rest_framework.mixins import ListModelMixin,CreateModelMixin,UpdateModelMixin,RetrieveModelMixin,DestroyModelMixin class PublishSerializers(serializers.ModelSerializer): class Meta: model = Publish fields = "__all__" class PublishView(GenericViewSet,ListModelMixin,CreateModelMixin,UpdateModelMixin,RetrieveModelMixin,DestroyModelMixin): queryset = Publish.objects.all() serializer_class = PublishSerializers

第二种方法:

通过ModelViewSet高度封装 ,ModelViewSet里面封装了GenericViewSet,ListModelMixin,CreateModelMixin,UpdateModelMixin,RetrieveModelMixin,DestroyModelMixin 

from rest_framework.viewsets import ModelViewSet class PublishSerializers(serializers.ModelSerializer): class Meta: model = Publish fields = "__all__" class PublishView(ModelViewSet): queryset = Publish.objects.all() serializer_class = PublishSerializers



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有