REST-framework快速构建API四部曲
2021-06-14 22:05
标签:nbsp .data 目录 generic ted serial 函数 auth 资源 代码目录结构: 一、使用原生APIView 使用rest-framework原生的APIView实现过程: 以url(r‘^books/$‘, views.BookView.as_view(),name="books")为例进行流程分析, 1、views.BookView.as_view()==>APIView的as_view方法==>父类【View】的as_view方法 2、View的as_view方法实际上是返回了View下的view方法 3、view实际上是执行了dispatch方法 4、dispatch执行过程是去找对应的get/post/put/delete/patch方法 代码实现如下: urls文件 PublishView用于处理publishes的get和post,获取多个资源的情况 PublishDetailView用于处理publishes/1/的get、put、delete,获取单个资源的情况 views文件 使用rest-framework原生的APIView,按照上面说的流程,最后进入dispatch方法,所以只需要我们自己重写get/post/put/delete等方法即可。 serializer文件 通过ModelSerializer类,指定model和fields进行序列化操作。 原生APIView的缺点: 针对每个model,需要自己写API的各种方法,代码重复程度很高。 进一步解决办法:使用mixins 二、使用mixins mixins在上一步的基础上进行了进一步的封装,也就是把多资源情况下的GET/POST以及单资源情况下的GET/POST/PUT/DELETE进行了再次封装,只要我们指定集成的类,然后重写对应的方法即可,urls也不用变更。 使用mixins还是有代码重复的缺点,每个model表都需要重写这一堆方法和类。 三、使用generics 使用generics可以很好的避免上面的问题,他直接包含了多资源和单资源情况下的所有方法,而不需要重写get、post、put、delete方法,甚至还包括patch方法。 但是这里还有一个缺点,就是单资源和多资源的视图函数以及url都是两份,是不是可以进行一步封装呢? 四、使用viewsets 使用viewsets可以通过在as_view中传参进一步简化操作。 在as_view中传入{动作:方法}的字典给action参数,然后通过getattr和setattr方法进行参数解析,然后通过dispatch中执行对应的方法。 urls文件 views文件 这就是最终版本,对于一个model表,url两个,一个ModelViewSet类就可以轻易的实现一个API! REST-framework快速构建API四部曲 标签:nbsp .data 目录 generic ted serial 函数 auth 资源 原文地址:https://www.cnblogs.com/skyflask/p/10398679.htmlurl(r‘^publishes/$‘, views.PublishView.as_view(),name="publish"),
url(r‘^publishes/(?P
from rest_framework.views import APIView
# Publish表
class PublishView(APIView):
def get(self,request):
publish_list = Publish.objects.all()
ps = PublishModelSerializers(publish_list, many=True)
return Response(ps.data)
def post(self,request):
# post请求的数据
ps = PublishModelSerializers(data=request.data)
if ps.is_valid():
print(ps.validated_data)
ps.save() # create方法
return Response(ps.data)
else:
return Response(ps.errors)
class PublishDetailView(APIView):
def get(self, request, pk):
publish = Publish.objects.filter(pk=pk).first()
ps = PublishModelSerializers(publish)
return Response(ps.data)
def put(self, request, pk):
publish = Publish.objects.filter(pk=pk).first()
ps = PublishModelSerializers(publish, data=request.data)
if ps.is_valid():
ps.save()
return Response(ps.data)
else:
return Response(ps.errors)
def delete(self, request, pk):
Publish.objects.filter(pk=pk).delete()
return Response()
from rest_framework import serializers
from app01.models import *
# 为queryset,model对象做序列化
class PublishSerializers(serializers.Serializer):
name = serializers.CharField()
email = serializers.CharField()
class PublishModelSerializers(serializers.ModelSerializer):
class Meta:
model=Publish
fields="__all__"
from rest_framework import mixins
from rest_framework import generics
class AuthorView(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView):
queryset=Author.objects.all()
serializer_class =AuthorModelSerializers
def get(self,request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self,request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class AuthorDetailView(mixins.RetrieveModelMixin,mixins.DestroyModelMixin,mixins.UpdateModelMixin,generics.GenericAPIView):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers
def get(self,request,*args, **kwargs):
return self.retrieve(request,*args, **kwargs)
def delete(self,request,*args, **kwargs):
return self.destroy(request,*args, **kwargs)
def put(self,request,*args, **kwargs):
return self.retrieve(request,*args, **kwargs)
from rest_framework import mixins
from rest_framework import generics
class AuthorView(generics.ListCreateAPIView):
queryset=Author.objects.all()
serializer_class =AuthorModelSerializers
class AuthorDetailView(generics.RetrieveUpdateDestroyAPIView):
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers
url(r‘^books/$‘, views.BookViewSet.as_view({"get":"list","post":"create"}),name="book_list"),
url(r‘^books/(?P
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializers