使用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_bookdef update(self, instance, validated_data):# 更新逻辑Book.objects.filter(pk=instance.pk).update(**validated_data)# 针对更新加的两句话,区分instanceupdated_book = Book.objects.get(pk=instance.pk)return updated_bookclass 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.errorsif 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 = Bookfields = "__all__"# fields = ["title", "price"]# exclude = ["pub_date"]
二、基于GenericAPIView的接口实现
GenericAPIView是继承的APIView,然后又实现了一些自定义的方法。
1、urls.py
path('sers/publish/', views.PublishView.as_view()),# ?p<pk> 有名分组,这样写之后会行成 pk=\d 的形式re_path('sers/publish/(?P<pk>\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 GenericAPIViewclass PublishSerializers(serializers.ModelSerializer):class Meta:model = Publishfields = "__all__"class PublishView(GenericAPIView):# 定义2个类全局变量;以后复用这个类的时候,只改两个全局变量;queryset = Publish.objects.all()serializer_class = PublishSerializersdef 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 = PublishSerializersdef 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> 有名分组,这样写之后会行成 pk=\d 的形式re_path('sers/publish/(?P<pk>\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,DestroyModelMixinclass PublishSerializers(serializers.ModelSerializer):class Meta:model = Publishfields = "__all__"class PublishView(ListModelMixin,CreateModelMixin,GenericAPIView):# 定义2个类全局变量;以后复用这个类的时候,只改两个全局变量;queryset = Publish.objects.all()serializer_class = PublishSerializersdef 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 = PublishSerializersdef 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,RetrieveUpdateDestroyAPIViewclass PublishSerializers(serializers.ModelSerializer):class Meta:model = Publishfields = "__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