zoukankan      html  css  js  c++  java
  • Python正课141 —— DRF 进阶2 请求、响应与视图

    本文内容皆为作者原创,如需转载,请注明出处:https://www.cnblogs.com/xuexianqi/p/13267845.html

    一:请求和响应

    1.请求

    # 请求对象
    # from rest_framework.request import Request
        def __init__(self, request, parsers=None, authenticators=None,
                     negotiator=None, parser_context=None):
            # 二次封装request,将原生request作为drf request对象的 _request 属性
            self._request = request
        def __getattr__(self,item):
        	return getattr(self._request,item)
    # 请求对象.data:前端以三种编码方式传入的数据,都可以取出来
    # 请求对象..query_params 与Django标准的request.GET相同,只是更换了更正确的名称而已。
            
    

    2.响应

    #from rest_framework.response import Response
     def __init__(self, data=None, status=None,
                     template_name=None, headers=None,
                     exception=False, content_type=None):
            
    #data:你要返回的数据,字典
    #status:返回的状态码,默认是200,
    	-from rest_framework import status在这个路径下,它把所有使用到的状态码都定义成了常量
    #template_name 渲染的模板名字(自定制模板),不需要了解
    #headers:响应头,可以往响应头放东西,就是一个字典
    #content_type:响应的编码格式,application/json和text/html;
    
    # 浏览器响应成浏览器的格式,postman响应成json格式,通过配置实现的(默认配置)
    #不管是postman还是浏览器,都返回json格式数据
    # drf有默认的配置文件---》先从项目的setting中找,找不到,采用默认的
    # drf的配置信息,先从自己类中找--》项目的setting中找---》默认的找
    	-局部使用:对某个视图类有效
            -在视图类中写如下
            from rest_framework.renderers import JSONRenderer
            renderer_classes=[JSONRenderer,]
        -全局使用:全局的视图类,所有请求,都有效
        	-在setting.py中加入如下
            REST_FRAMEWORK = {
                'DEFAULT_RENDERER_CLASSES': (  # 默认响应渲染类
                    'rest_framework.renderers.JSONRenderer',  # json渲染器
                    'rest_framework.renderers.BrowsableAPIRenderer',  # 浏览API渲染器
                )
            }
    

    二:视图

    # 两个视图基类
    APIView
    GenericAPIView
    

    1.基于APIView写接口

    #### views.py
    from rest_framework.generics import GenericAPIView
    from app01.models import Book
    from app01.ser import BookSerializer
    # 基于APIView写的
    class BookView(APIView):
        def get(self,request):
            book_list=Book.objects.all()
            book_ser=BookSerializer(book_list,many=True)
    
            return Response(book_ser.data)
        def post(self,request):
            book_ser = BookSerializer(data=request.data)
            if book_ser.is_valid():
                book_ser.save()
                return Response(book_ser.data)
            else:
                return Response({'status':101,'msg':'校验失败'})
    
    
    class BookDetailView(APIView):
        def get(self, request,pk):
            book = Book.objects.all().filter(pk=pk).first()
            book_ser = BookSerializer(book)
            return Response(book_ser.data)
    
        def put(self, request,pk):
            book = Book.objects.all().filter(pk=pk).first()
            book_ser = BookSerializer(instance=book,data=request.data)
            if book_ser.is_valid():
                book_ser.save()
                return Response(book_ser.data)
            else:
                return Response({'status': 101, 'msg': '校验失败'})
    
        def delete(self,request,pk):
            ret=Book.objects.filter(pk=pk).delete()
            return Response({'status': 100, 'msg': '删除成功'})
        
    #models.py
    class Book(models.Model):
        name=models.CharField(max_length=32)
        price=models.DecimalField(max_digits=5,decimal_places=2)
        publish=models.CharField(max_length=32)
    #ser.py
    class BookSerializer(serializers.ModelSerializer):
        class Meta:
            model=Book
            fields='__all__'
    # urls.py
    path('books/', views.BookView.as_view()),
    re_path('books/(?P<pk>d+)', views.BookDetailView.as_view()),
    

    2.基于GenericAPIView写的接口

    # views.py
    class Book2View(GenericAPIView):
        #queryset要传queryset对象,查询了所有的图书
        # serializer_class使用哪个序列化类来序列化这堆数据
        queryset=Book.objects
        # queryset=Book.objects.all()
        serializer_class = BookSerializer
        def get(self,request):
            book_list=self.get_queryset()
            book_ser=self.get_serializer(book_list,many=True)
    
            return Response(book_ser.data)
        def post(self,request):
            book_ser = self.get_serializer(data=request.data)
            if book_ser.is_valid():
                book_ser.save()
                return Response(book_ser.data)
            else:
                return Response({'status':101,'msg':'校验失败'})
    
    
    class Book2DetailView(GenericAPIView):
        queryset = Book.objects
        serializer_class = BookSerializer
        def get(self, request,pk):
            book = self.get_object()
            book_ser = self.get_serializer(book)
            return Response(book_ser.data)
    
        def put(self, request,pk):
            book = self.get_object()
            book_ser = self.get_serializer(instance=book,data=request.data)
            if book_ser.is_valid():
                book_ser.save()
                return Response(book_ser.data)
            else:
                return Response({'status': 101, 'msg': '校验失败'})
    
        def delete(self,request,pk):
            ret=self.get_object().delete()
            return Response({'status': 100, 'msg': '删除成功'})
        
     #url.py
        # 使用GenericAPIView重写的
        path('books2/', views.Book2View.as_view()),
        re_path('books2/(?P<pk>d+)', views.Book2DetailView.as_view()),
    

    3.基于GenericAPIView和5个视图扩展类写的接口

    from rest_framework.mixins import  ListModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin
    # views.py
    class Book3View(GenericAPIView,ListModelMixin,CreateModelMixin):
    
        queryset=Book.objects
        serializer_class = BookSerializer
        def get(self,request):
            return self.list(request)
    
        def post(self,request):
            return self.create(request)
    
    class Book3DetailView(GenericAPIView,RetrieveModelMixin,DestroyModelMixin,UpdateModelMixin):
        queryset = Book.objects
        serializer_class = BookSerializer
        def get(self, request,pk):
            return self.retrieve(request,pk)
    
        def put(self, request,pk):
            return self.update(request,pk)
    
        def delete(self,request,pk):
            return self.destroy(request,pk)
    # urls.py
        # 使用GenericAPIView+5 个视图扩展类  重写的
        path('books3/', views.Book3View.as_view()),
        re_path('books3/(?P<pk>d+)', views.Book3DetailView.as_view()),
    

    4.使用ModelViewSet编写5个接口

    # views.py
    from rest_framework.viewsets import ModelViewSet
    class Book5View(ModelViewSet):  #5个接口都有,但是路由有点问题
        queryset = Book.objects
        serializer_class = BookSerializer
        
    # urls.py
    # 使用ModelViewSet编写5个接口
        path('books5/', views.Book5View.as_view(actions={'get':'list','post':'create'})), #当路径匹配,又是get请求,会执行Book5View的list方法
        re_path('books5/(?P<pk>d+)', views.Book5View.as_view(actions={'get':'retrieve','put':'update','delete':'destroy'})),
    
    
    

    5.源码分析ViewSetMixin

    # 重写了as_view
    # 核心代码(所以路由中只要配置了对应关系,比如{'get':'list'}),当get请求来,就会执行list方法
    for method, action in actions.items():
        #method:get
        # action:list
        handler = getattr(self, action)
        #执行完上一句,handler就变成了list的内存地址
        setattr(self, method, handler)
        #执行完上一句  对象.get=list
        #for循环执行完毕 对象.get:对着list   对象.post:对着create
    
    
    

    6.继承ViewSetMixin的视图类

    # views.py
    from rest_framework.viewsets import ViewSetMixin
    class Book6View(ViewSetMixin,APIView): #一定要放在APIVIew前
        def get_all_book(self,request):
            print("xxxx")
            book_list = Book.objects.all()
            book_ser = BookSerializer(book_list, many=True)
            return Response(book_ser.data)
        
    # urls.py
        #继承ViewSetMixin的视图类,路由可以改写成这样
        path('books6/', views.Book6View.as_view(actions={'get': 'get_all_book'})),
    
    

    三:补充

    在pycharm中查看类的继承关系

    1594180914084

  • 相关阅读:
    JAVA-初步认识-第十二章-多线程创建方式一继承
    JAVA-初步认识-第十二章-主线程运行示例
    JAVA-初步认识-第十二章-JVM中的多线程分析
    JAVA-初步认识-第十二章-面向对象(Jar包)
    JAVA-初步认识-第十二章-面向对象(导入import)
    ecstore-kvcache里表结构
    ecstore-app接口
    ecstore与淘宝sdk的autoload加载顺序问题
    正则匹配<{$vcode}>变量
    电子面单纸打印时固定高度18cm,到底是多少px
  • 原文地址:https://www.cnblogs.com/xuexianqi/p/13267845.html
Copyright © 2011-2022 走看看