drf day 04

今日内容详细

一、drf之请求与响应

 1.1 Request类Response类

  1. 继承APIView后,请求对象:request------> 每一次的请求都是一个新的request。

  通过http请求,给了django,django看不懂http请求,所以把他包装成了request,所以你才能点body,点get,点什么什么,搞到对象里面了,我们drf又给他重新包装,

但是原来的request也在里面,所以每一次请求都是新的request;我们每次请求都是三次握手,然后返回一坨东西,我们把这一坨东西称为response,一出django就变成了http响应,

来到了前端,展示给客户看,然后这个http就结束了。

  2.  Request类的属性或方法(drf的请求)

    data:POST、PUT、PATCH请求方式解析的数据

      -原生django,put提交的数据在request.POST是取不到的

    ② query_params

    ③ 其他的用起来跟之前一样用(FILES,,method,path...)----> __getattr__

  3.  Response类(drf的响应)

      Response(字典,列表)

   Response的属性:

     (1)data = None, 字典和列表都给了data---->data会序列化成json格式字符串,返回给前端(其实是放在http响应的body中了)

     (2)status = None,  针对http响应的状态码,默认是200,如果新增的话改成201更好

     (3)headers=None,  http的响应头,它是一个字典{name:lqz}

        -如何向响应头里面增加数据?          

class TextView(APIView);
    def get(slef,request):
        d = {'name':'wyn','age':18}
        # 原生django如何向响应头里面添加数据,四件套都可以
        res = HttpResponse(json.dumps(d))
        res = JsonRsponse(d)
        res['rrr'] = yyy
        return res
        # 新的Response向响应头里面添加数据非常简单,直接使用headers参数
        return Response(d,status=HTTP_201_CREATE,headers={'name':'wyn'})

      (4) template_name=None     了解即可,就是在浏览器中看到的好看的页面,是指定的模板

      (5)content_type=None  响应的编码格式(默认是json格式,但是这句话又不完全准确,具体看是向浏览器发送请求,还是向postman发送的请求)【你以为请求有编码,响应就没有编码了吗】

1.2 drf能够解析的请求编码,响应编码

    一. 能够解析的请求编码

       1. 默认能解析:

        -urlencoded

        -form-data

        -json

       2. 其实通过配置完成:在项目中是没有配置的,但是在drf内置的配置文件中提前配好了(项目中配置文件,内置中也有配置文件)

        ①-drf也是有两套配置,一套是项目中的配置(settings.py),一套是默认的配置

       ②-drf的配置文件( restframework/settings.py )中有DEFAULE_PARSER_CLASSES(是默认的解析类

                -'rest_framework.parsers.JSONParser',可以解析json格式
                -'rest_framework.parsers.FORMParsers',可以解析urlencoded格式
                -'rest_framework.parsers.MultiParsers',可以解析form-data格式

        ③-想让我们的接口只能接收json格式

          方式一:全局配置--->就是在项目中配置文件--->那么以后的所有的接口都遵循这个项目中的配置   

             但是这种方法不好,无法上传文件了  

REST_FRAMEWORK = {
                    'DEFAULT_PARSER_CLASSES': [
                        'rest_framework.parsers.JSONParser',
                        # 'rest_framework.parsers.FormParser',
                        # 'rest_framework.parsers.MultiPartParser',# 这两句都注释掉了,那么drf只能解析JSON格式了,成功完成我们想要的需求
                    ],
                   }

          方式二:局部配置--->在views.py中配置

from rest_framework.parsers import JSONParser,FormParser,MultiPartParser

Class TestView(APIView):
                parser_classes = [JSONParser,FormParser,MultiPartser]   # 这种是三种格式都可以编码
                parser_classes = [JSONParser]  # 只能编码Json格式

  -总结

    解析类的使用顺序优先用视图自己的,然后用项目配置文件的,最后用内置的(可以理解为从近到远)

  -实际项目如何配置

    -基本上都运行JSONParser,FormParser

    -如果上传文件只允许MultiParser                                                 

   二、能够处理的响应编码

      1.  如果使用浏览器,显示好看的样子,如果用postman看到json格式

        -默认情况下显示的编码是根据客户端类型决定的

      2.  全局配置:在项目的配置文件    

RESR_FRAMEWORK = {
                'DEFAULT_RENDERE_CLASSES':[
                    'rest_framework.renderers.JSONRenderer',    # json格式
                    'rest_framework.renderers.BrowsableAPIRenderer'    # 浏览器的格式(就是rest_framework好看的样子)
                ]
            }

      3.  局部配置:--->在views.py中配置     

from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer

Class TestView(APIView):
                renderer_classes = [JSONRenderer,]

  -实际编码中,响应编码一般不去自己配,就用默认的

 

二、两个视图基类

  2.1 基于APIView写5个接口

lass UserView(APIView):
    def get(self, request):
        book_list = User.objects.all()
        ser = UserSerializer(instance=book_list, many=True)
        return Response(ser.data)

    def post(self, request):
        ser = UserSerializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': "新增成功"}, status=201)
        else:
            return Response({'code': 101, 'msg': ser.errors})


class UserDetailView(APIView):
    def get(self, request, pk):
        book = User.objects.filter(pk=pk).first()
        ser = UserSerializer(instance=book)
        return Response(ser.data)

    def put(self, request, pk):
        book = User.objects.filter(pk=pk).first()
        ser = UserSerializer(instance=book, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': "修改成功"}, status=201)
        else:
            return Response({'code': 101, 'msg': ser.errors})

    def delete(self, request, pk):
        User.objects.filter(pk=pk).delete()
        return Response('')

  2.2 基于GenericAPIView写五个接口

from rest_framework.generics import GenericAPIView
class UserView(GenericAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def get(self, request):
        book_list = self.get_queryset()
        ser = self.get_serializer(instance=book_list, many=True)
        return Response(ser.data)

    def post(self, request):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': "新增成功"}, status=201)
        else:
            return Response({'code': 101, 'msg': ser.errors})


class UserDetailView(GenericAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    def get(self, request, pk):
        book = self.get_object()
        ser = self.get_serializer(instance=book)
        return Response(ser.data)

    def put(self, request, pk):
        book = self.get_object()
        ser = self.get_serializer(instance=book, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': "修改成功"}, status=201)
        else:
            return Response({'code': 101, 'msg': ser.errors})

    def delete(self, request, pk):
        self.get_queryset().filter(pk=pk).delete()
        return Response('')

作业:

  views.py

 使用GenericAPIView写出book的5个接口


from rest_framework.generics import GenericAPIView


class BookView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request):
        book_list = self.get_queryset()
        ser = self.get_serializer(instance=book_list, many=True)
        return Response(ser.data)

    def post(self, request):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': "新增成功"}, status=201)
        else:
            return Response({'code': 101, 'msg': ser.errors})


class BookDetailView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request, pk):
        book = self.get_object()
        ser = self.get_serializer(instance=book)
        return Response(ser.data)

    def put(self, request, pk):
        book = self.get_object()
        ser = self.get_serializer(instance=book,data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code':100,'msg':"修改成功"},status=201)
        else:
            return Response({'code':101,'msg':ser.errors})

    def delete(self,request,pk):
        self.get_queryset().filter(pk=pk).delete()
        return Response('')

  serializer

from rest_framework import serializers

from .models import Book

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

使用面向对象,写5个父类, 继承GenericAPIView+某几个父类后,就有某几个接口

class AllBook(GenericAPIView):
    def get(self,request):
        book_list = Book.objects.all()
        res = self.serializer_class(instance=book_list,many=True)
        return Response(res.data)
    
class PostBook(GenericAPIView):
    def post(self,request):
        res = self.serializer_class(data=request.data)
        if res.is_valid():
            res.save()
            return Response({'code':100,'msg':'新增成功'},status=201)
        else:
            return Response({'code':100,'msg':res.errors})
        
class OneBook(GenericAPIView):
    def get(self,request,pk):
        book = self.serializer_class(instance=book)
        return Response(res.data)
    
class PutBook(GenericAPIView):
    def put(self,request,pk)
        book = self.get_object()
        res = self.serializer_class(instance=book,data=request.data)
        if res.is_valid():
            res.save()
            return Response({'code':100,'msg':'修改成功'})
        esle:
            return Response({'code':101,'msg':res.errors})
      
class DeleteBook(GenericAPIView):
    def delete(self,request,pk):
        self.get_queryset().filter(pk=pk).delete()
        return Response('')
    
class BookView(AllBook,PostBook):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    
class BookDetailView(OneBook,PutBook,DeleteBook):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

 

posted @ 2022-09-29 21:03  W-Y-N  阅读(24)  评论(0)    收藏  举报