• Django REST Framework 数码宝贝


      读了我这篇博客, 你会刷新对面对对象的认知, 之前的面对对象都是LJ~~~

    表结构

    class Publisher(models.Model):
        name = models.CharField(max_length=32)
    
        def __str__(self):
            return self.name
    
    
    class Author(models.Model):
        name = models.CharField(max_length=32)
    
        def __str__(self):
            return self.name
    
    
    class Book(models.Model):
        title = models.CharField(max_length=32)
        pub_date = models.DateField()
        CHOICES = ((1, 'Python'), (2, 'Go'), (3, 'linux'))
        category = models.IntegerField(choices=CHOICES)
        publisher = models.ForeignKey(to='Publisher', on_delete=models.CASCADE)
        authors = models.ManyToManyField(to='Author')
    
        def __str__(self):
            return self.title

     原路由:

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^books/$', views.BookListView.as_view()),
        url(r'book/(?P<pk>d+)$', views.BookDetailView.as_view()),
    
        url(r'^publishers/$', views.PublisherView.as_view()),
        url(r'publishers/(?P<pk>d+)$', views.PublisherDetailView.as_view()),
    
    ]

    原始版:

      获取出版社信息  

    # 获取出版社信息
    class PublisherView(APIView):
        """使用Django REST framework 内置的序列化"""
    
        def get(self,request):
            """Json格式返回所有的书籍信息"""
            queryset = models.Publisher.objects.all()
            ser_obj = ModelPublisherSerlizer(queryset, many=True)
            return Response(ser_obj.data)
    
        def post(self, request):
            ser_obj = ModelPublisherSerlizer(data=request.data)
            if ser_obj:
                ser_obj.save()
                return Response('ok')
            else:
                return Response(ser_obj.errors)

      获取具体某个出版社信息 查 改 删 -- > 

    # 获取具体某个出版社信息
    class PublisherDetailView(APIView):
    
        def get(self,pk):
            publisher_ob = models.Publisher.objects.filter(pk=pk)
            publisher_obj = models.Publisher.objects.filter(pk=pk).first()
            print("publisher_ob", publisher_ob, "publisher_obj", publisher_obj)
    
            if publisher_obj:
                ser_obj = ModelPublisherSerlizer(publisher_obj)
                return Response(ser_obj.data)
            else:
                return Response("无效的id")
    
        def put(self, request, pk):
            publisher_obj = models.Publisher.objects.filter(pk=pk).first()
    
            if publisher_obj:
                ser_obj = ModelPublisherSerlizer(instance=publisher_obj, data=request.data, partial=True)
                if ser_obj.is_valid():
                    ser_obj.save()
                    return Response(ser_obj.data)
                else:
                    return Response(ser_obj.errors)
            else:
                return Response("没有这本书")
    
    
        def delete(self,pk):
            publisher_obj = models.Publisher.objects.filter(pk=pk)
    
            if publisher_obj:
                publisher_obj.delete()
                return Response("删除成功")
            else:
                return Response("没有这本书")

    进化版:

      把出版社相关信息封装起来

    class CemericView(APIView):
        """视图中可能用到的配置和方法封装起来"""
        queryset = None
        serializer_class = None
    
        def get_queryset(self):
            # 让每次请求来的时候都先查一次数据
            return self.queryset.all()
    
    
    class ListMinxin(object):
        def get(self, request):
            queryset = self.get_queryset()
            ser_obj = self.serializer_class(queryset, many=True)
            return Response(ser_obj.data)
    
    class CreateMixin(object):
        def post(self, request):
            ser_obj = self.serializer_class(data=request.data)
            if ser_obj:
                ser_obj.save()
                return Response('ok')
            else:
                return Response(ser_obj.errors)
    
    # 获取出版社信息
    class PublisherView(CemericView, ListMinxin, CreateMixin):
    
        queryset = models.Publisher.objects.all()
        serializer_class = ModelPublisherSerlizer

     

    超级进化版:

      把某个出版社的信息也封装起来

    class GemericView(APIView):
        """视图中可能用到的配置和方法封装起来"""
        queryset = None
        serializer_class = None
    
        def get_queryset(self):
            # 让每次请求来的时候都先查一次数据
            return self.queryset.all()
    
        def get_obj(self, request, pk, *args, **kwargs):
            return self.get_queryset().filter(pk=pk).filter(pk=pk).first()
    class ListMinxin(object):
        def get(self, request):
            queryset = self.get_queryset()
            ser_obj = self.serializer_class(queryset, many=True)
            return Response(ser_obj.data)
    
    
    class CreateMixin(object):
        def post(self, request):
            ser_obj = self.serializer_class(data=request.data)
            if ser_obj.is_valid():
                ser_obj.save()
                return Response('ok')
            else:
                return Response(ser_obj.errors)
    
    
    # 获取出版社信息
    class PublisherView(GemericView, ListMinxin, CreateMixin):
    
        queryset = models.Publisher.objects.all()
        serializer_class = ModelPublisherSerlizer
    
    
    class RetrieveMixin(object):
        def get(self, request, pk, *args, **kwargs):
            obj = self.get_obj(request, pk, *args, **kwargs)
            if obj:
                ser_obj = self.serializer_class(obj)
                return Response(ser_obj.data)
            else:
                return Response("无效的id")
    
    
    class UpdateMixin(object):
        def put(self, request, pk, *args, **kwargs):
            obj = self.get_obj(request, pk, *args, **kwargs)
    
            if obj:
                ser_obj = ModelPublisherSerlizer(instance=obj, data=request.data, partial=True)
                if ser_obj.is_valid():
                    ser_obj.save()
                    return Response(ser_obj.data)
                else:
                    return Response(ser_obj.errors)
            else:
                return Response("没有这本书")
    
    
    class DelMixin(object):
        def delete(self, request, pk, *args, **kwargs):
            obj = self.get_obj(request, pk, *args, **kwargs)
            print(obj)
            # print(obj.filter(pk = pk))
    
            if obj:
                obj.delete()
                return Response("删除成功")
            else:
                return Response("没有这本书")
    
    
    # 获取具体某个出版社信息
    class PublisherDetailView(GemericView, RetrieveMixin, UpdateMixin, DelMixin):
        queryset = models.Publisher.objects.all()
        serializer_class = ModelPublisherSerlizer

      如果在写一个api 的话 只需要3行代码, 

        但是 封装的代码好像有点多, 继承关系有点乱,

          其实框架本身提供了内置方法, 

    from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin

    注意: 单纯的导入 不能成功, 因为 此方法中不是以 get ,post 等命名的, 导致 MVC模型中 as.view(), 找不到 请求的方式, 需要 对 这些方法进行进一步封装

     就有了下面的内置方法

    from rest_framework.generics import ListCreateAPIView,RetrieveDestroyAPIView
    
    #这个包里里面 封装了 各种用于API 开发的浏览器 请求方式, 及组合方式, 直接调用即可

      一共 7行 代码解决

    from rest_framework.generics import ListCreateAPIView, RetrieveDestroyAPIView
    
    # 获取出版社信息
    class PublisherView(ListCreateAPIView):
    
        queryset = models.Publisher.objects.all()
        serializer_class = ModelPublisherSerlizer
    
    # 获取具体某个出版社信息
    class PublisherDetailView(RetrieveDestroyAPIView):
        queryset = models.Publisher.objects.all()
        serializer_class = ModelPublisherSerlizer

    究极进化版:

      上面超级进化版 一张表要写两个视图 定义queryset和serializer_class 重复,

      而且  路由也需要重复, 显然, 究极进化是不允许的~~

      

        重写了as_view()方法,实现了根据请求的方法执行具体的类方法

       路由注册的时候,利用actions参数,实现路由的定向分发 而不是简单的 反射

    url(r'authors/$', views.AuthorViewSet.as_view(actions={'get': 'list', 'post': 'create'})),  # 作者列表
    url(r'authors/(?P<pk>d+)/$', views.AuthorViewSet.as_view(
            actions={'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})
            ),  # 作者详情   

        路由都重复写两条:

       还可以利用内置的DefaultRouter来实现路由的注册

    from rest_framework.routers import DefaultRouter
    
    router = DefaultRouter()
    router.register('authors', views.AuthorViewSet)
    
    urlpatterns += router.urls
    from rest_framework.viewsets import ModelViewSet
    class AuthorViewSet(ModelViewSet):
        """
            list()
            create()
            retrieve()
            update()
            destroy()
    
        """
        queryset = models.Author.objects.all()
        serializer_class = AuthorModelSerializer

    总结:  

      建议用以下两种方式

  • 相关阅读:
    课后作业
    使用类的静态字段和构造函数,我们可以跟踪某个类所创建对象的个数。请写一个类,在任何时候都可以向它查询“你已经创建了多少个对象?”。
    课程作业·02
    课程作业01
    课程作业02 将课程中的所有动手动脑的问题以及课后实验性的问题,整理成一篇文档。
    课程作业01 模仿JavaAppArguments.java示例,编写一个程序,此程序从命令行接收多个数字,求和之后输出结果。
    《大道至简》第一章伪代码
    Vue2.0版英雄联盟助手,我的第一个小开源项目
    二级下拉菜单的三种实现方法——CSS 、JS、 jQuery
    关于清除浮动 and position的一些注意点
  • 原文地址:https://www.cnblogs.com/konghui/p/10268393.html
Copyright © 2020-2023  润新知