使用Django的DRF框架,基于restful接口规范的增删改查(查所有)查(查一个)操作,一般默认有如下规范:
/book/ GET 查看所有资源,返回所有资源; /book/ POST 添加资源,返回添加的资源;
/book/1 GET 查看某一个资源,返回这一个资源;
/book/1 PUT 编辑某一个资源,返回编辑之后的这个资源;
/book/1 DELETE 删除某一个资源,返回空;
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是继承的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()
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是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