• ModelSerializer和视图


    ModelSerializer

    ModelSerializer和ModelForm组件很相似

    1.自当义类继承ModelSerializer

    from rest_framework.serializers import ModelSerializer
    class BookModelSerializers(ModelSerializer):
       class Meta:
           model=models.Book
           fields="__all__"

    2.处理get请求:

    url(r'^book/$', views.BookView.as_view())
    from rest_framework.views import APIView
    from rest_framework.response import Response
    class BookView(APIView):
        def get(self, request):
            book_list = models.Book.objects.all()
            bs = BookModelSerializers(book_list, many=True)
            return Response(bs.data)  # 序列化接口,将bs的所有内容都返回
    #在处理get请求时只是将BookSerializers换为BookModelSerializers

    3.处理post请求:

     def post(self,request):
            bs=BookModelSerializers(data=request.data,)
            if bs.is_valid():# 校验字段接口
                bs.save() #创建记录接口create
                return Response(bs.data)  # 序列化接口
            return Response(bs.errors)  # 序列化接口
    接受到数据就,进行校验,如果合格,就存起来(save),否则就将错误显示出来

    4.处理查看指定个数据,编辑和删除请求:

     url(r'^book/(d+)/$', views.BookDetailView.as_view())
    class BookDetailView(APIView):
        def get(self,request,pk):
            #对单个对象进行序列化
            book=models.Book.objects.filter(pk=pk).first()
            bs=BookModelSerializers(book)  #序列化具体的对象
            return Response(bs.data)
        def put(self,request,pk):
            book = models.Book.objects.filter(pk=pk).first()
            bs=BookModelSerializers(data=request.data,instance=book)
            if bs.is_valid():
                bs.save()
                return Response(bs.data)
            else:return Response(bs.errors)
        def delete(self, request,pk):
           models.Book.objects.filter(pk=pk).first().delete()
           #如果删除就返回空
           return Response()

           编写视图     

    使用ModelModelSerializer自定义编写视图
    url
     url(r'^book/$', views.BookView.as_view()),
     url(r'^book/(d+)/$', views.BookDetailView.as_view()),
    views.py
    from rest_framework.serializers import ModelSerializer
    class BookModelSerializers(ModelSerializer):
       class Meta:
           model=models.Book
           fields="__all__"
          
    from rest_framework.views import APIView
    from rest_framework.response import Response
    class BookView(APIView):
        def get(self,request):
            book_list=models.Book.objects.all()
             bs=BookModelSerializers(book_list,many=True)
            return Response(bs.data) # 序列化接口,将bs的所有内容都返回
        def post(self,request):
            print("request.data", request.data)
            bs=BookModelSerializers(data=request.data,)
            if bs.is_valid():# 校验字段接口
                bs.save() #创建记录接口create
                return Response(bs.data)  # 序列化接口
            return Response(bs.errors)  # 序列化接口
    BookView
    class BookDetailView(APIView):
        def get(self,request,pk):
            #对单个对象进行序列化
            book=models.Book.objects.filter(pk=pk).first()
            bs=BookModelSerializers(book)
            return Response(bs.data)
        def put(self,request,pk):
            book = models.Book.objects.filter(pk=pk).first()
            ###bs为序列化对象
            bs=BookModelSerializers(data=request.data,instance=book)
            if bs.is_valid():
                bs.save()
                return Response(bs.data)
            else:return Response(bs.errors)
        def delete(self, request,pk):
           models.Book.objects.filter(pk=pk).first().delete()
           #如果删除就返回空
           return Response()
    BookDetailView

    使用混合(mixins)

    url(r'^publish/$', views.PublishView.as_view()),
    url(r'^publish/(?P<pk>d+)/$', views.PublishDetailView.as_view()),
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from rest_framework.serializers import ModelSerializer
    from rest_framework import mixins
    from rest_framework import generics
    class PublishModelSerializer(ModelSerializer):
        class Meta:
            model=models.Publish
            fields="__all__"

    class PublishView(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView):
        queryset = models.Publish.objects.all()
        serializer_class = PublishModelSerializer
        def get(self,request, *args, **kwargs):
            return self.list(request, *args, **kwargs)
        def post(self,request, *args, **kwargs):
            return self.create(request, *args, **kwargs)
    PublishView
    class PublishDetailView(mixins.DestroyModelMixin,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,generics.GenericAPIView):
        queryset = models.Publish.objects.all()
        serializer_class = PublishModelSerializer
        def get(self, request, *args, **kwargs):
            return self.retrieve(request, *args, **kwargs)
        def put(self, request, *args, **kwargs):
            return self.update(request, *args, **kwargs)
        def delete(self, request, *args, **kwargs):
            return self.destroy(request, *args, **kwargs)
    PublishDetailView

    使用通用的基于类的视图

    url(r'^authors/$', views.AuthorsView.as_view()),
    url(r'^authors/(?P<pk>d+)/$', views.AuthorsDetailView.as_view()),
    class AuthorModelSerializers(ModelSerializer):
        class Meta:
            model=models.Author
            fields="__all__"
    class AuthorsView(generics.ListCreateAPIView):
        queryset = Author.objects.all()
        serializer_class = AuthorModelSerializers
    class AuthorsDetailView(generics.RetrieveUpdateDestroyAPIView):
        queryset = Author.objects.all()
        serializer_class = AuthorModelSerializers

    viewsets.ModelViewSet

    url

     url(r'^authors/$', views.AuthorsModelView.as_view({"get": "list", "post": "create"}),),
        url(r'^authors/(?P<pk>d+)/$', views.AuthorsModelView.as_view({
            'get': 'retrieve',
            'put': 'update',
            'delete': 'destroy'
        }),
    views
    from rest_framework.viewsets import  ModelViewSet
    from app01 import models
    class AuthorsModelView(ModelViewSet):
        queryset = models.Author.objects.all()
        serializer_class = AuthorModelSerializers
    使用viewsets.ModelViewSet方法便捷高效,具体流程:
    1.django启动
    Djago启动过后 views.AuthorsModelView.as_view({"get": "list", "post": "create"})
    和views.AuthorsModelView.as_view({
    'get': 'retrieve',
    'put': 'update',
    'delete': 'destroy'
    })都会被执行,找AuthorsModelView中的as_view方法,无此方法,去父类ModelViewSet查找
    2.ModelViewSet源码:
    class ModelViewSet(mixins.CreateModelMixin,
                       mixins.RetrieveModelMixin,
                       mixins.UpdateModelMixin,
                       mixins.DestroyModelMixin,
                       mixins.ListModelMixin,
                       GenericViewSet):  pass
    ModelViewSet中无s_view方法,去父类中查找
      CreateModelMixin中放着新建数据的函数
      RetrieveModelMixin中放着查看某条数据的函数
      UpdateModelMixin中放着更新数据的函数
      DestroyModelMixin中放着删除数据的函数
      ListModelMixin中放着展示全部数据的函数
      去GenericViewSet中查找as_view方法
    3.执行ViewSetMixin中的as_view
    GenericViewSet源码:
    class GenericViewSet(ViewSetMixin, generics.GenericAPIView):pass
    GenericViewSet中无as_view方法,向其父类中查找
    执行ViewSetMixin中的as_view。ViewSetMixin源码:
    
    
    class ViewSetMixin(object):
         def as_view(cls, actions=None, **initkwargs):
             def view(request, *args, **kwargs):
                self = cls(**initkwargs)
                self.action_map = actions
                 for method, action in actions.items():
                    handler = getattr(self, action)
                    setattr(self, method, handler)
                if hasattr(self, 'get') and not hasattr(self, 'head'):
                    self.head = self.get
                self.request = request
                self.args = args
                self.kwargs = kwargs
                return self.dispatch(request, *args, **kwargs)
         return csrf_exempt(view)
    找到as_view方法后,执行此方法返回view
    url(r'^authors/$', views.AuthorsModelView.as_view({"get": "list", "post": "create"}), ),
    url(r'^authors/(?P<pk>d+)/$', views.AuthorsModelView.as_view({
        'get': 'retrieve',
        'put': 'update',
        'delete': 'destroy'
    }),
    相当于:
    url(r'^authors/$', view),
    url(r'^authors/(?P<pk>d+)/$', view)
    这是启动django后就完成的工作,当用户发送请求时,view执行
    4.发送请求,执行ViewSetMixin中的view方法
    def view(request, *args, **kwargs):
        self = cls(**initkwargs)
        for method, action in actions.items():
            handler = getattr(self, action)
            setattr(self, method, handler)
        return self.dispatch(request, *args, **kwargs)

    最终的返回值时执行dispatch函数,在着之前的for循环的作用?
    需要知道actions是什么,但是函数中并没有actions这个值,在这里使用了闭包

    class ViewSetMixin(object):
         def as_view(cls, actions=None, **initkwargs):
             def view(request, *args, **kwargs):
                 for method, action in actions.items():pass
    在django启动时,执行as_view时传的有参数,
    views.AuthorsModelView.as_view({"get": "list", "post": "create"})
    在执行as_view时,默认参数actions接收到了{"get": "list", "post": "create"},在执行view时,使用这些值,不同的url执行actions接收值不同,
    在执行view时也不同
    for method, action in actions.items():
        handler = getattr(self, action)
        setattr(self, method, handler)
    method的值就是"get","post",action为"list","create"
    handeler的值为self.list/self.create
    setattr重新赋值,如setattr(self, "get",self.list)等同于再进行getattr(self,"get")

    5.执行self.dispatch,执行APIView中的dispatch

    AuthorsModelView,ModelViewSet,GenericViewSet,GenericAPIView
    均无dispatch方法,在APIView中有dispatch方法
    class APIView(View):
      def dispatch(self, request, *args, **kwargs):
         request = self.initialize_request(request, *args, **kwargs)
         self.request = request
          if request.method.lower() in self.http_method_names:
              handler = getattr(self, request.method.lower(),
                                      self.http_method_not_allowed)
          else:
             handler = self.http_method_not_allowed
          response = handler(request, *args, **kwargs)
          return self.response
    执行APIView中的dispatch方法:
    handler = getattr(self, request.method.lower(),self.http_method_not_allowed)
    执行反射时,如果发来的请求get,此时handler不再是self.get,而是self.list.是因为在执行ViewSetMixin中的view方法时
    setattr(self, method, handler)重新赋值了
    执行handler函数,response=self.list(request, *args, **kwargs),去AuthorsModelView中list方法
    class ListModelMixin(object):
        def list(self, request, *args, **kwargs):
            queryset = self.filter_queryset(self.get_queryset())
            page = self.paginate_queryset(queryset)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)
            serializer = self.get_serializer(queryset, many=True)
            return Response(serializer.data)
    handler执行后的结果返回给response,dispatch函数将response返回给view,view在页面上显示出来
  • 相关阅读:
    保利尼奥离中超如肖申克救赎 没人再说人傻钱多
    Apache -- XAMPP Apache 无法启动原因及解决方法
    Android -- 工程目录解释
    正向代理和反向代理
    PHP -- 页面传值的6种获取方法
    实用小工具 -- 在线查看别人网站流量
    web前端 -- onkeydown、onkeypress、onkeyup、onblur、onchange、oninput、onpropertychange的区别
    WampServer -- “You don't have permission to access /phpmyadmin/ on this server.”
    PHP -- 字符串
    PHP -- 类和对象基础入门
  • 原文地址:https://www.cnblogs.com/zgf-666/p/9206367.html
Copyright © 2020-2023  润新知