• 请求与响应、视图


    请求与响应、视图

    请求

    #请求对象,把原来的request重新封装
    	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
        #.取值的时候从self._request(request)去获取对应的数据
        def __getattr__(self,item):
        	return getattr(self._request,item)
    #前端三种编码格式传入的数据,都可以从请求对象.data取
    #请求对象.query_params与Django中的request.GET相同,只是换了个合适的名称
    

    响应

    #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(ok)
    	from rest_framework import status路径,把所有的状态码定义成了常量,这样使用status.常量名
    	return Response({'status':status.HTTP_208_ALREADY_REPORTED})
    #headers	响应头,是字典可以放值,Response.headers['key']=values
    #content_type	响应的编码格式,postman响应成application/json,浏览器是text/html
    #template_name 渲染的模板名字(自定制模板),不需要了解
    #drf默认的配置文件查找顺序
    	项目的settings.py>>>rest_framework.settings
    #drf的配置信息,先从自己类>>>项目的setting.py>>>rest_framework.settings
    
    
    

    视图

    #两个视图基类
    	APIView
    	GenericAPIView
    #基于APIView写接口
        from rest_framework.views import APIView
        from app01.models import Book
        from app01.ser import BookSerializer
        from rest_framework import status
        class BookAPIView(APIView):
            def get(self,request,*args,**kwargs):
                #没有pk,查所有
                if not kwargs.get('pk'):
                    book_list = Book.objects.all()
                    book_ser = BookSerializer(book_list,many=True)#many序列化多条
                    return Response(book_ser.data)
                else:
                    #查单个
                    book = Book.objects.filter(pk=kwargs.get('pk')).first()
                    book_ser = BookSerializer(book)
                    return Response(book_ser.data)
            #新增一个
            def post(self,request):
                book_ser = BookSerializer(data=request.data)
                if book_ser.is_valid():
                    book_ser.save()#基于Serializer的需要在序列化类写create方法
                    return Response(book_ser.data)
                else:
                    return Response({'status':101,'msg':'校检失败'})
    
            def put(self,request,*args,**kwargs):
                book = Book.objects.filter(pk=kwargs.get('pk')).first()
                #修改需要传入修改的对象,修改的数据,序列化类写update方法
                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,*args,**kwargs):
                book = Book.objects.filter(pk=kwargs.get('pk')).delete()
                return Response({'status':100,'msg':'删除成功'})
    	#序列化类是Serializer,需要在序列化类写create、update方法,ModelSerializer不用
    	    def create(self, validated_data):
                book_obj = Book.objects.create(**validated_data)
                return book_obj
            def update(self, instance, validated_data):
                instance.name = validated_data.get('name')
                instance.price = validated_data.get('price')
                instance.author = validated_data.get('author')
                instance.save()
                return instance
        #路由配置
            #BookAPIView
            re_path('bookapiview/(?P<pk>d+)',views.BookAPIView.as_view()),
            path('bookapiview/',views.BookAPIView.as_view()),
    #基于GenericAPIView写接口  
    from rest_framework.generics import GenericAPIView
    class BookGenericAPIView(GenericAPIView):
        queryset = Book.objects.all()
        serializer_class = BookModelSerializer
        def get(self,*args,**kwargs):
            if kwargs.get('pk'):
                book = Book.objects.filter(pk=kwargs.get('pk')).first()
                book_ser = self.get_serializer(book)
                return Response(book_ser.data)
            else:
                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':'校检失败'})
        def put(self,request,*args,**kwargs):
            book = Book.objects.filter(pk=kwargs.get('pk')).first()
            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,*args,**kwargs):
            Book.objects.filter(pk=kwargs.get('pk')).delete()
            return Response({'status':100,'msg':'删除成功'})
        #路由配置
            # BookGenericAPIView
            re_path('bookgeneric/(?P<pk>d+)', views.BookGenericAPIView.as_view()),
            path('bookgeneric/', views.BookGenericAPIView.as_view()),
    #基于GenericAPIView和5个视图扩展类写接口
        from rest_framework.generics import GenericAPIView
        from rest_framework.mixins import ListModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin
        class BookGenerricmixin(GenericAPIView,ListModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin):
            queryset = Book.objects.all()
            serializer_class = BookModelSerializer
            def get(self,request,*args,**kwargs):
                pk = kwargs.get('pk')
                if pk:
                    return self.retrieve(request,pk)
                else:
                    return self.list(request)
            def post(self,request):
                return self.create(request)
            def put(self,request,*args,**kwargs):
                pk = kwargs.get('pk')
                if pk:
                    return self.update(request,pk)
                else:
                    return Response({'status':101,'msg':'没有pk值'})
            def delete(self,request,*args,**kwargs):
                pk=kwargs.get('pk')
                if pk:
                    return self.destroy(request,pk)
                else:
                    return Response({'status':101,'msg':'没有pk值'})
            #路由配置
            # Bookgenerricmixin
            path('bookgenerricmixin/', views.BookGenerricmixin.as_view()),
            re_path('bookgenerricmixin/(?P<pk>d+)', views.BookGenerricmixin.as_view()),
    

    使用ModelViewSet编写的5个接口手写路由

    #每个请求方式对应的方法
    path('books5/', views.BookModelViewSet.as_view(actions={'get':'list','post':'create'}))
        re_path('books5/(?P<pk>d+)', views.BookModelViewSet.as_view(actions={'get':'retrieve','put':'update','delete':'destroy'}))
    

    源码分析ViewMixin

    # 重写了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
    

    继承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'})),
    

    查看继承关系

    作者:linqiaobao
    本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    217MySQL读写分离mysqlproxy
    shell脚本自动化安装LAMP
    Mybatis的如何根据下划线_,百分号%模糊查询escape的作用
    springboot下MVC的MessageConverters和静态资源位置的配置
    全局性事务控制如何在springboot中配置
    最详细的@Transactional讲解
    常用网址
    truncate、drop、delete区别
    CommandLineRunner、ApplicationRunner 接口
    交叉编译,为什么需要交叉编译
  • 原文地址:https://www.cnblogs.com/linqiaobao/p/13355771.html
Copyright © 2020-2023  润新知