请求与响应、视图

请求与响应、视图

请求

#请求对象,把原来的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
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/linqiaobao/p/13355771.html