APIview执行流程、Request对象源码分析、序列化器介绍和快速使用

APIview执行流程

1.基于APIview+JsonResponse编写接口

之前基于django原生的View编写接口
drf为我们提供了一个类(APIView)以后使用drf写视图类都要继承这个类及其子类
APIViews本身就是继承了Django原生的View

class BookView(APIView):
    def get(self, request):
        books = Book.objects.all()
        book_list = []
        for book in books:
            book_list.append({'name': book.name, 'price': book.price, 'publish': book.publish})
        return JsonResponse(book_list, safe=False)

2.基于APIview+Response编写接口

class BookViews(APIView):
    def get(self, request):
        books = Books.objects.all()
        book_list = []
        for book in books:
            book_list.append({"name": book.name, "price": book.price})
        return Response(book_list) #字典和列表都可以序列化

3.APIView的执行流程

路由中写的: path('books/', views.BookView.as_view())
请求来了执行第二个参数 views.BookView.as_view()()
现在的as_view是APIView的as_view

APIView的as_view方法:view还是原生的view 但是以后再也没有csrf验证了
	@classmethod
    #调用父类的as_view 父类是django原生的view
    def as_view(cls, **initkwargs):
        #view就是把django原生View中的as_view方法中的闭包函数view拿出来了
        view = super().as_view(**initkwargs)
        #相当于在所有的方法上面加上了装饰器 以后所有的请求方式都不用csrf验证了
        return csrf_exempt(view)

路由匹配成功 执行csrf_exempt(view)(request)

去view(view本质没变还是那个view)中的as_view中的闭包函数viewself.dispatch(request, *args, **kwargs)其中的self是BookView视图类的对象

视图类没有就去他的父类APIView的dispatch找:

    def dispatch(self, request, *args, **kwargs):
        #request是django原生的request 老的request
        request = self.initialize_request(request, *args, **kwargs)
        #把老的request包装成新的request 这个request是drf提供的Request类的对象
        #这个request就是新的了 
        #self._request = request 这是老的 把老的request放到self变成新的request
        self.request = request
		#把新的request放到了BookView视图类里面
        try:
            #执行了三大认证【】使用的都是新的reuqest
            self.initial(request, *args, **kwargs)
            #跟cbv一摸一样
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed

            response = handler(request, *args, **kwargs)

        except Exception as exc:
            response = self.handle_exception(exc)
		#在执行三大认证和视图类的方法过程中 如果出现了异常 都能捕获 ---全局异常捕获
        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response

总结:

​ 1.去除csrf认证

​ 2.包装新的request

​ 3.执行视图类的方法之前执行三大认证

​ 4.在执行三大认证和视图类过程中出现异常 全局异常捕获

​ 5.以后用的request都是新的request

Request对象源码分析

老的:django.core.handlers.wsgi.WSGIRequest

新的:from rest_framework.request import Request

新的 request._request就是老的

Request源码:

方法:__getattr__ 在视图类的方法中 执行request.method 新的Request是没有method的 就触发了新的Request的__getattr__方法的执行
    def __getattr__(self, attr):
        try:
            #从老的request中反射出 想要获取的属性
            return getattr(self._request, attr)
        except AttributeError:
            return self.__getattribute__(attr)
request.data  这是一个方法 包装成了属性
	以后无论是什么请求 放在body中提交的数据 都从request.data中取 取出来就是字典 无论哪种格式
request.query_params 这是一个方法 包装成了属性
	get请求携带的参数 以后都从这里面取
    query_params:查询参数----restful规范中 请求地址中带过滤参数
    qurey_params 和 request._request.GET一样
request.FILES 这是一个方法 包装成了属性
	前端提交过来的文件从这里取 
    和原生的不一样 可以直接存

总结:

​ 1.新的request用起来和老的一样 执行request.method 新的取不到 就去老的取 触发__getattr__ 反射获取

​ 2.request.data 无论什么编码、请求 只要在body中就从这里取 结果是字典

​ 3.request.query_params 就是request._request.GET

​ 4.上传文件从request.FILES取

序列化器介绍和快速使用

在写接口时 需要序列化和反序列化 反序列化就需要做数据校验

drf提供了固定写法 按照固定写法写就能完成以上条件

提供了两个类:SerializerModelSerializer

只需要写自己的类 继承drf提供的序列化类 使用其中的某些方法 即可

使用APIView+序列化类+Response完成接口编写

1.序列化类基本使用 序列化多条

serializer.py:

建立serializer.py文件在里面编写序列化类

from rest_framework import serializers

class BookSerializers(serializers.Serializer):
    name = serializers.CharField()
    #序列化的字段 这里写要序列化的字典
    price = serializers.CharField()

views.py

class BookView(APIView):
    def ger(self,request):
        books = Books.objects.all()
        ser=BookSerializer(instance=books,many=True)
        #instance要序列化的数据books many=True 标识可以序列化多条 
        return Response(ser.data)
        #无论字典还是列表都可以被序列化

2.序列化类基本使用 序列化单条

serializer.py:没变 还是一样的

建立serializer.py文件在里面编写序列化类

from rest_framework import serializers

class BookSerializers(serializers.Serializer):
    name = serializers.CharField()
    #序列化的字段 这里写要序列化的字典
    price = serializers.CharField()

views.py

class BookView(APIView):
    def ger(self,request,pk):
        books = Books.objects.filter(pk=pk).first()
        ser=BookSerializer(instance=books)
        #instance要序列化的数据books many=True 标识可以序列化多条
        return Response(ser.data)
        #无论字典还是列表都可以被序列化

反序列化

1.反序列化的新增

serializer.py:

from .models import Books
from rest_framework import serializers

class BookSerializer(serializers.Serializer):
    name = serializers.CharField()
    #序列化的字段 这里写要序列化的字典
    price = serializers.CharField()

    def create(self, validated_data):
        #保存
        #validated_data检验过后的数据{name price}
        #保存到数据库
        books = Books.objects.create(**validated_data)
        return books 

views.py:

class BooksView(APIView):
    def post(self,request):
        #前端提交的要保存的数据 -- 检验数据  -- 存进数据库
        ser=BookSerializer(data=request.data)
        #把前端传入的要保存的数据 给data参数
        #检验数据
        if ser.is_valid():
        #保存 -- 需要自己写 要在系列化类BookSerializer中写create方法
            ser.save() #调用ser.save()自动触发create 保存起来
            return Response({'code':100,'msg':'新增成功','result':ser.data})
        else:
            return Response({'code':101,'msg':ser.errors})

2.反序列化修改

serializer.py:

    def update(self, instance, validated_data):
        #instance  要修改的对象
        #validated_data 校验过后的对象
        instance.name = validated_data.get('name')
        instance.price = validated_data.get('price')
        instance.save() 
        return instance

views.py:

class BookUpDate(APIView):
    def put(self,request,pk):
        books = Books.objects.filter(pk=pk).first()
        #反序列化保存---借助于序列化类
        ser = BookSerializer(data=request.data,instance=books)
        if ser.is_valid():
            ser.save()  #写update方法
            return Response({'code':100,'msg':'修改成功','result':ser.data})
        else:
            return Response({'code':101,'msg':ser.errors})

3.删除

views.py:

class BookDelete(APIView):
    def delete(self,request,pk):
        Books.objects.filter(pk=pk).first().delete()
        return Response({'code':100,'msg':'删除成功'})

反序列化校验

序列化类反序列化类 数据校验功能  -- 类比form组件
 局部钩子
 全局钩子

局部钩子:

    def validate_name(self,name):
        if name == 'xxx':
            raise ValidationError('NAME XXX IS ERROR')
        else:
            return name

全局钩子:

    def validate(self,attrs):
        if attrs.get('name') == attrs.get('price'):
            raise ValidationError('A NAME DOES EQUAL A PRICE')
        else:
            return attrs
posted @ 2023-02-01 20:28  李李大冒险  阅读(50)  评论(0编辑  收藏  举报
  1. 1 不可撤销
  2. 2 小年兽 程嘉敏
  3. 3 迷人的危险3 FAFA
  4. 4 山楂树之恋 程佳佳
  5. 5 summertime cinnamons / evening cinema
  6. 6 不谓侠(Cover 萧忆情Alex) CRITTY
  7. 7 神武醉相思(翻自 优我女团) 双笙(陈元汐)
  8. 8 空山新雨后 音阙诗听 / 锦零
  9. 9 Wonderful U (Demo Version) AGA
  10. 10 广寒宫 丸子呦
  11. 11 陪我看日出 回音哥
  12. 12 春夏秋冬的你 王宇良
  13. 13 世界が终わるまでは… WANDS
  14. 14 多想在平庸的生活拥抱你 隔壁老樊
  15. 15 千禧 徐秉龙
  16. 16 我的一个道姑朋友 双笙(陈元汐)
  17. 17 大鱼 (Cover 周深) 双笙(陈元汐)
  18. 18 霜雪千年(Cover 洛天依 / 乐正绫) 双笙(陈元汐) / 封茗囧菌
  19. 19 云烟成雨(翻自 房东的猫) 周玥
  20. 20 情深深雨濛濛 杨胖雨
  21. 21 Five Hundred Miles Justin Timberlake / Carey Mulligan / Stark Sands
  22. 22 斑马斑马 房东的猫
  23. 23 See You Again Wiz Khalifa / Charlie Puth
  24. 24 Faded Alan Walker
  25. 25 Natural J.Fla
  26. 26 New Soul Vox Angeli
  27. 27 ハレハレヤ(朗朗晴天)(翻自 v flower) 猫瑾
  28. 28 像鱼 王贰浪
  29. 29 Bye Bye Bye Lovestoned
  30. 30 Blame You 眠 / Lopu$
  31. 31 Believer J.Fla
  32. 32 书信 戴羽彤
  33. 33 柴 鱼 の c a l l i n g【已售】 幸子小姐拜托了
  34. 34 夜空中最亮的星(翻自 逃跑计划) 戴羽彤
  35. 35 慢慢喜欢你 LIve版 戴羽彤
  36. 36 病变 戴羽彤
  37. 37 那女孩对我说 (完整版) Uu
  38. 38 绿色 陈雪凝
  39. 39 月牙湾 LIve版 戴羽彤
像鱼 - 王贰浪
00:00 / 04:45
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 周有才

作曲 : 周有才

这是一首简单的歌

没有什么独特

试着代入我的心事

它那么幼稚

像个顽皮的孩子

多么可笑的心事

只剩我还在坚持

谁能看透我的眼睛

让我能够不再失明

我要记住你的样子

像鱼记住水的拥抱

像云在天空中停靠

夜晚的来到

也不会忘了阳光的温暖

我要忘了你的样子

像鱼忘了海的味道

放下所有梦和烦恼

却放不下回忆的乞讨

多么可笑的心事

只剩我还在坚持

谁能看透我的眼睛

让我能够不再失明

记住你的样子

像鱼记住水的拥抱

像云在天空中停靠

夜晚的来到

也不会忘了阳光的温暖

我要忘了你的样子

像鱼忘了海的味道

放下所有梦和烦恼

却放不下回忆的乞讨

只剩自己就好