视图的进化三部曲

视图三部曲

第一种方式:

使用混合(mixins):

serialize.py

class AuthorModelSerializers(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = "__all__"

urls.py

 url(r'authors/$', views.AuthoView.as_view(),name="authors"),
 url(r'authors/(?P<pk>\d+)/$', views.AuthorDetailView.as_view(),name="authordetail")

views.py

from rest_framework import mixins
from rest_framework import generics

class AuthoView(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,pk,*args,**kwargs):
        return self.retrieve(request,pk,*args,**kwargs)

    def delete(self,request,pk,*args,**kwargs):
        return self.destroy(request,pk,*args,**kwargs)

    def put(self,request,pk,*args,**kwargs):
        return self.update(request,pk,*args,**kwargs)

因为每一个表都进行一次的重复操作会使得代码冗余,所以使用封装好的mixin会稍微简洁一些,

mixin:
    ListModelMxin        #查看
    CreateModelMixin     #新建
    DestoryModelMixin    #删除
    RetrieveModelMixin   #查看具体一条
    UpdateModelMixin     #更新

第二种方式:

使用通用的基于类的视图

通过使用mixin类,我们使用更少的代码重写了这些视图,但我们还可以再进一步。REST框架提供了一组已经混合好(mixed-in)的通用视图,我们可以使用它来简化我们的views.py模块。

#其他不变:

from rest_framework import mixins
from rest_framework import generics

class AuthoView(generics.ListCreateAPIView):
    queryset=Author.objects.all()
    serializer_class=AuthorModelSerializers
class AuthorDetailView(generics.RetrieveUpdateDestroyAPIView):
    queryset=Author.objects.all()
    serializer_class=AuthorModelSerializers

继承关系做了进一步的封装,方法也进行了更加简练的优化,方法全部写进了源码内。

第三种方式:

viewsets.ModelViewSet

views.py

from rest_framework import viewsets
class AuthorModelView(viewsets.ModelViewSet):
    queryset=Author.objects.all()
    serializer_class=AuthorModelSerializers

urls.py

url(r'authors/$', views.AuthorModelView.as_view({"get":"list","post":"create"}),name="authors"),

url(r'authors/(?P<pk>\d+)/$', views.AuthorModelView.as_view({"get":"retrieve","put":"update","delete":"destroy"}),name="authordetail"),

2趟线使用同一个类,在urls中的as_view()中加入参数,让不同的请求方式走不同的方法。

这里看源码中遇到的一个薄弱点,这里记录一下:

def foo(action=None,**kwargs):
    print(action)
    print(kwargs)

foo(**{"d":5})
print("______________")
foo({"d":5})
#总结:**字典等同于关键字传参

None
{'d': 5}
______________
{'d': 5}
{}

这个传参方式需要注意一下。

总结:

从源码中摘出来的部分代码,组成了最后的流程。

 流程:
         (1)url(r'^authors/$', views.AuthorModelView.as_view({"get":"list","post":"create"}),name="author"),
         (2)url(r'^authors/$', ViewSetMixin.as_view({"get":"list","post":"create"}),name="author"),
         (3)url(r'^authors/$', ViewSetMixin类下的view),
          一旦访问 /authors/:
          ViewSetMixin
             def  view():
                for method, action in actions.items(): # {"get":"list","post":"create"}
                    handler = getattr(self, action)    # self.list  self.create
                    setattr(self, method, handler)     #self.get  =  self.list   self.post=self.post   
                 #这里取到了get,post等方法后,赋值给handler,然后通过setattr()
          #执行dispatch方法 self.dispatch(request,
*args, **kwargs)
                     APIView类下的self.dispatch #这个dispatch方法是APIView里面的,返回的是response.
# 分发 if request.method.lower() in self.http_method_names:
              #getattr(self,"get") --->self.list
              #getattr(self,"post") --->self.create
handler
= getattr(self,request.method.lower())      #这里真正执行的是list,create方法。             
            #最终执行handler(). response
= handler(request, *args, **kwargs) # self.list()
            #将response返回。 return response

  

猜你喜欢

转载自www.cnblogs.com/geogre123/p/9747265.html