drf请求与响应与GenericAPIView的使用

drf请求与响应

Request

'继承APIView后,请求对象:request'
1.Request类属性或方法
-Request不再是传入视图的request对象,而是封装扩展了功能的Request
-Request对象的数据是自动根据前端发送数据的格式进行解析之后的结果,无论前端发送的哪种格式的数据,我们都可以以统一的方式读取数据

1.1.data
-request.data可以解析POST、PUT、PATCH请求方式的请求体数据
-put提交的数据在原生django的方法request.POST中是取不到的
1.2.query_params
-request.query_params与django原生的request.POST相同
1.3其他的方法(FILES,method,path...)用起来和原生django一样

Response类

1.data=None
-将字典或列表序列化成json格式字符串,在返回给http响应的body中

2.status=None
-http响应的状态码,默认是200,可以改为你需要使用的状态码
-drf帮我们把所有的状态码都做成了常量,可以直接导进来用
from rest_framework import status
return HttpResponse(status=status.HTTP_201_CREATED)

3.headers=None
-http用于存放响应头信息的字典
b = {'name': 'barry'}
# 在响应头中放数据
res = JsonResponse(b)
res['aaa'] = 'bbb'
return res

4.template_name=None
-模板名称,在浏览器中可以看到好看的页面

5.content_type=None
响应数据的编码格式,默认为json格式

drf能解析的请求编码

1.默认能解析的编码格式
-urlencoded、form-data、json
-我们可以解析这些编码格式其实是通过配置完成的,项目中没有配置,是在drf内置的配置文件中提前配好的
-drf有两套配置,一套是项目中的配置(settings.py),一套是默认的配置
-drf的配置文件settings.py中的DEFAULTS的DEFAULT_PARSER_CLASSES是默认的解析类

2.在DEFAULT_PARSER_CLASSES的解析类有配置的三个解析类
['rest_framework.parsers.JSONParser',--可以解析json格式
'rest_framework.parsers.FormParser',--可以解析urlencoded格式
'rest_framework.parsers.MultiPartParser']--可以解析from-data格式

'如果我们想让我们的接口只能接受我们指定的格式'
4.方式1:全局配置
在项目配置文件中添加配置,这样以后所有的接口都遵循这个配置
REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
        # 'rest_framework.parsers.FormParser',
        # 'rest_framework.parsers.MultiPartParser',
    ],
}

5.方式2:局部配置
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser


class TesView(APIView):
    parser_classes = [JSONParser]
'''
-解析顺序:优先使用视图类自己的,在用项目配置文件,最后才是内置
-实际项目中如何配置
大部分都运行JSONParser,FormParser,如果上传文件只允许MultiPartParser
'''

响应编码

1.默认情况下,响应的编码时根据客户端类型决定的

2.全局配置:在项目的配置文件
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',--json格式
        'rest_framework.renderers.BrowsableAPIRenderer',--浏览器的格式
    ]
}

3.局部配置
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer


class TesView(APIView):
    renderer_classes = [JSONRenderer]
'实际编码中,响应编码一般不配,就使用默认的配置'

2个视图基类

1.drf提供了一个顶层的视图APIView,可以通过继承APIView写视图,之后我们写的代码可能重复代码比较多,就可以使用面向对象的继承、封装

2.GenericAPIView继承了APIView,我们用GenericAPIView时就不需要继承APIView
2.1导入
from rest_framework.generics import GenericAPIView

2.2类属性
queryset = User.objects.all()
serializer_class = UserModelSerialize

2.3方法
self.get_queryset()---获取所有要序列化的数据
self.get_serializer()---获取要使用的序列化类
self.get_object()---根据pk获取单个要序列化的数据

基于GenericAPIView写5个接口

from rest_framework.generics import GenericAPIView


class UserView(GenericAPIView):
    queryset = User.objects.all()
    serializer_class = UserModelSerializer
    def get(self, request):
        user_list = self.get_queryset()
        ser = self.get_serializer(instance=user_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 UserDataView(GenericAPIView):
    queryset = User.objects.all()
    serializer_class = UserModelSerializer
    def get(self, request, pk):
        user = self.get_object()
        ser = self.get_serializer(instance=user)
        return Response(ser.data)

    def put(self, request, pk):
        user = self.get_object()
        ser = self.get_serializer(instance=user, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 10, '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('')

作业

1.使用GenericAPIView写出book的5个接口

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

    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 BookDataView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookModelSerializer

    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': 10, 'msg': '修改成功'}, status=201)
        else:
            return Response({'code': 101, 'msg': ser.errors})

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

2.使用面向对象,写5个父类, 继承GenericAPIView+某几个父类后,就有某几个接口(新增1条 GenericAPIView+Create)

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

class Post():
    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 Get():
    def get(self, request, pk):
        book = self.get_object()
        ser = self.get_serializer(instance=book)
        return Response(ser.data)

class Put():
    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': 10, 'msg': '修改成功'}, status=201)
        else:
            return Response({'code': 101, 'msg': ser.errors})

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

class BookView(GenericAPIView, AllGet, Post):
    queryset = Book.objects.all()
    serializer_class = BookModelSerializer

class BookDataView(GenericAPIView, Get, Put, Delete):
    queryset = Book.objects.all()
    serializer_class = BookModelSerializer

3.9个视图子类

class GenericAllGet(GenericAPIView, AllGet):
    pass
class GenericPost(GenericAPIView, Post):
    pass
class GenericAllGetPost(GenericAPIView, AllGet, Post):
    pass
class GenericGet(GenericAPIView, Get):
    pass
class GenericPut(GenericAPIView, Put):
    pass
class GenericDelete(GenericAPIView, Delete):
    pass
class GenericGetPut(GenericAPIView, Get, Put):
    pass
class GenericGetDelete(GenericAPIView, Get, Delete):
    pass
class GenericPutDelete(GenericAPIView, Put, Delete):
    pass
class GenericGetPutDelete(GenericAPIView, Get, Put, Delete):
    pass

class BookView(GenericAllGet):
    queryset = Book.objects.all()
    serializer_class = BookModelSerializer

class BookDataView(GenericGetPutDelete):
    queryset = Book.objects.all()
    serializer_class = BookModelSerializer

4.两个视图类 合二为一(99.99%)

99.99%
posted @   无言以对啊  阅读(77)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示

目录导航