反序列化类校验部分源码解析、断言、drf之请求、drf之响应、视图组件介绍及两个视图基类、GenericAPIView、5个视图扩展类

反序列化类校验部分源码解析

视图类中的ser.is_valid(),就会执行校验 校验通过返回True 不通过返回Flase

is_valid()

入口:
'''
ser.is_valid()是序列化类的对象 就假设序列化类是假设序列化类是BookSerializer -- 找is_valid() 
没有--去ModelSerializer里找 
没有--去父类Serializer里找
没有--去父类BaseSerializer中找--找到了
'''
   def is_valid(self, *, raise_exception=False):
        if not hasattr(self, '_validated_data'):
            #首次判断self里有没有_validated_data 没有直接走try
            try: 
                self._validated_data = self.run_validation(self.initial_data)
            #首次 self序列化类的对象 属性中没有_validation 一定会走这句【核心】走过就有了 以后再来不走
            except ValidationError as exc:
                self._validated_data = {}
                self._errors = exc.detail
            else:
                self._errors = {}

        if self._errors and raise_exception:
            raise ValidationError(self.errors)
            #如果raise_exception是True 就会抛异常 统一处理 返回信息

        return not bool(self._errors)
    
self._validated_data = self.run_validation(self.initial_data)
#一定不要直接摁ctrl点进去
'''
这里的self是序列化类BookSerializer的对象 
找run_validation切记不是直接ctrl点进去查看 
要从自身开始找顺序是先在BookSerializer里找
没有--去父类 ModelSerializer里找
没有--去父类Serializer里找--找到了
而不是直接点进去 查看的是Field中的run_validation
''''
raise_exception=True 校验没通过会直接抛异常就不用if判断了  

run_validation()

    def run_validation(self, data=empty):
        (is_empty_value, data) = self.validate_empty_values(data)
        #字段自己的和validates方法
        if is_empty_value:
            return data
        value = self.to_internal_value(data)
        #局部钩子
        try:
            self.run_validators(value)
            value = self.validate(value)
            #全局钩子 --- 如果在BookSerializer中写了validate,优先走他
        except (ValidationError, DjangoValidationError) as exc:
            raise ValidationError(detail=as_serializer_error(exc)        return value
            #局部钩子 self.to_internal_value(data)
             self是BookSerializer的对象,从根上找
                                  
      def to_internal_value(self, data):
        ret = OrderedDict()
        errors = OrderedDict()
        fields = self._writable_fields
        for field in fields:
            validate_method = getattr(self, 'validate_' + field.field_name, None)
           #self BookSerializer的对象 反射validate_name
            try:
            	validated_value = validate_method(validated_value)
                 #在执行BookSerializer类中的validate_name方法 传入了要校验的数据 validated_value就是name参数
            except ValidationError as exc:
                errors[field.field_name] = exc.detail
            else:
                set_value(ret, field.source_attrs, validated_value)
        if errors:
            raise ValidationError(errors)

        return ret                     

断言

关键字 assert 有什么用?  断定你是不是xxx 不是就直接抛异常

if判断:
#	name = 'lqz'

# if name == 'lqz':
#     print('对了')
# else:
#     # print('错了')
#     raise Exception('名字不为lqz,不能继续走了')

断言:
assert name=='xxx'
print('后续代码')
判断是不是 是走后续代码
判断不是 抛异常

drf之请求

1.Request能够解析前的前端传入的编码格式

方式一:在继承自APIView及其子类的视图类中配置(局部配置)
总共有三个:from rest_framework.parsers import JSONParser,FormParser,MultiPartParser
class BookView(APIView):
    parser_classes = [JSONParser,]
    
方式二:在配置文件中配置(影响所有 全局配置)
django有套默认配置 每个项目有个配置
drf有套默认配置 每个项目也有个默认配置
 REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        # 'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.FormParser',
        # 'rest_framework.parsers.MultiPartParser',
    ],
}
想用哪个就打开哪一个

方式三:全局配了1个 某视图类想要3个
只需要在视图类配置三个即可
因为先从视图类自身找 找不到去项目的drf配置中找 再找不到就去drf默认的配置找

2.Request类有哪些属性的方法

data  在data里面获取数据

__getattr__ 反射出老的request.method

query_params 等于 request.GET

drf之响应

1.Response能够响应的编码格式

drf 是djngo的一个app 所以要注册
drf响应 如果使用浏览器和postman访问同一个窗口 
	#drf做了个判断,如果是浏览器,好看一些,如果是postman只要json数据
     方式一:在视图类中写(局部配置)
         from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
    class BookView(APIView):
    	renderer_classes=[JSONRenderer,]
       #想用哪个方式就在列表里填哪个 支持多个
    
    方式二:在项目配置文件中写(全局配置)
    	 REST_FRAMEWORK = {
      'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],
}
    #想用哪个方式就打开哪个方式
    
    方式三:使用顺序(一般用内置的即可)
    	优先使用视图类中的配置 其次使用项目配置文件中的配置 最后使用内置的
    

2.Resposne的源码属性或方法

drf的源码分析:
	from rest_framework.response import Response
    视图类的方法返回时 return Respones 走他的__init__,__init__可以传哪些参数

	Response init可以传的参数
      def __init__(self, 
                   data=None,
                   status=None,
                   template_name=None,
                   headers=None,
                   exception=False,
                   content_type=None)
        data:
        	之前写的ser.data 可以是字典、列表或字符串 -- 序列化后返回给前端 -- 前端在响应体中看到的就是这里面的数据
        status:
        	http响应状态码 默认是200 可以自己更改 
            #drf在status包下 把所有的http响应状态码都写了一边 是常量
            #导入模块from rest_framework.status import HTTP_200_OK
        	#Response('dddd',status=status.HTTP_201_OK)
            
        template_name:
        	修改响应模板的样子 BrowsableAPIRenderer浏览器的样子是定死的 可以自己定制
        headers:
        	响应头 headers = {k:v}样式
            djgno怎么在响应头中加东西
            obj = HttpResponse('ddd')
            obj['xxx']='yyy'
            return obj
        content_type:
            响应编码格式 一般不动
            
#重点:data、status,headers

视图组件介绍及两个视图基类

APIView 和 View区别
	1.传入视图类的是drf的request 不是djngo的request
    2.以后用的都是新的request
    3.全局异常捕获
    4.三大认证

两个视图基类

APIView :
    类属性: renderer_classes 响应格式
    		parser_classes	 能够解析的请求格式
        	authentication_classes 认证类
            throttle_classes 频率类
            permission_classes 权限类
            
    

1.APIView+ModelSerializer+Resposne写5个接口

第一层:初级

model.py

from django.db import models
#图书表
class Books(models.Model):
    name = models.CharField(max_length=32)
    price = models.CharField(max_length=32)

    publish = models.ForeignKey(to="Publish", on_delete=models.CASCADE)
    authors = models.ManyToManyField(to="Author")

 #定制写在外键所在的表下面
    def publish_dict(self):
        return {'name':self.publish.name,'add':self.publish.add}

    def author_list(self):
        l = []
        for author in self.authors.all():
            l.append({'name':author.name,'phone':author.phone})
        return l

#出版社表
class Publish(models.Model):
    name = models.CharField(max_length=32)
    add = models.CharField(max_length=32)

#作者表
class Author(models.Model):
    name = models.CharField(max_length=32)
    phone = models.CharField(max_length=32)
    gender = models.CharField(max_length=2)


url.py

from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/',views.BooksView.as_view()),
    path('books/<int:pk>/',views.BookView.as_view())

views.py

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
# Create your views here.
from .models import Books
from .serialize import BookSerializers
#不需要筛选条件的视图类
class BooksView(APIView):
    #获取所有图书信息
    def get(self,request):
        books = Books.objects.all()
        ser = BookSerializers(instance=books,many=True)
        return Response(ser.data)
	#新增图书信息
    def post(self,request):
        ser = BookSerializers(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code':100,'msg':'新增成功'})
        else:
            return Response({'code':101,'msg':ser.errors})
#需要额外条件的视图类
class BookView(APIView):
    #获取某一本图书信息
    def get(self,request,pk):
        books = Books.objects.filter(pk=pk).first()
        ser = BookSerializers(instance=books)
        return Response(ser.data)
	#修改某一本图书信息
    def put(self,request,pk):
        books = Books.objects.filter(pk=pk).first()
        ser = BookSerializers(instance=books,data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '修改成功','result':ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})
	#删除某一本图书信息
    def delete(self,request,pk):
        Books.objects.filter(pk=pk).first().delete()
        return Response({'code': 100, 'msg': '删除成功'})

serialize.py

from rest_framework import serializers
from .models import Books

class BookSerializers(serializers.ModelSerializer):
    class Meta:
        model = Books
        fields =['name','price','publish','authors','publish_dict','author_list']
        extra_kwargs = {
            'publish':{'write_only':True},
            'authors':{'write_only':True},
        }
#用了ModelSerializer继承了Serializers 大部分请求不用写create和update 底层直接写好了 

基于GenericAPIView扩展类

属性:
	queryset:	要序列化或者反序列化的表模型数据
    serializer_class: 使用的序列化类
    lookup_field: 查询单条的路由分组分出来的字段名
    filter_backends:	过滤类的配置
    pagination_class:	分页类的配置
    
方法:
	get_queryset: 获取要序列化的对象
    get_object:   获取要序列化的单个对象
    get_serializer:获取序列化类 
    get_serializer_class:差不多 一般不调用它 重写他
    filter_queryset: 过滤有关

第二层:中级

只优化了views.py

这样的好处是 以后不管写哪一个视图类 里面的代码都不用动了

只需要更改queryset = Books.objects.all()和 serializer_class = BookSerializers即可

class BooksView(GenericAPIView):
    queryset = Books.objects.all()
    serializer_class = BookSerializers
    def get(self,request):
        books = self.get_queryset()  #可以用self.queryset拿到 但不要这样用 有一个方法 可扩展性更高 后期可以重写get_queryset
        ser = self.get_serializer(instance=books,many=True) #同理 但后期重写写的是get_serializer_class 指定哪个序列化类来序列化
        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':'新增成功'})
        else:
            return Response({'code':101,'msg':ser.errors})

class BookView(GenericAPIView):
    queryset = Books.objects.all()
    serializer_class = BookSerializers
    def get(self,request,pk):
        books = self.get_object() #获取某一条 源码中定义 lookup_field = 'pk' 所以获取的参数必须是pk 可以在全局中修改
        ser = self.get_serializer(instance=books)
        return Response(ser.data)

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

    def delete(self,request,pk):
        self.get_object().delete()
        return Response({'code': 100, 'msg': '删除成功'})

基于GenericAPIView+5个视图扩展类

5个视图扩展类

from rest_framework.mixins import CreateModelMixin, UpdateModelMixin, DestroyModelMixin, RetrieveModelMixin, ListModelMixin

CreateModelMixin:新增  -- 方法 --create
UpdateModelMixin:修改  -- 方法 --update
DestroyModelMixin:删除  -- 方法 --destroy
RetrieveModelMixin:查询单个  -- 方法 --retrieve
ListModelMixin:查询多个  -- 方法 --list

只优化了views.py

class BooksView(GenericAPIView,ListModelMixin,CreateModelMixin):
    queryset = Books.objects.all()
    serializer_class = BookSerializers
    def get(self,request):
       return self.list(request)

    def post(self,request):
            return self.create(request)

class BookView(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):
    queryset = Books.objects.all()
    serializer_class = BookSerializers
    def get(self,request,*args,**kwargs):
        return self.retrieve(request,*args,**kwargs)

    def put(self,request,*args,**kwargs):
            return self.update(request,*args,**kwargs)

    def delete(self,request,*args,**kwargs):
        return self.destroy(request,*args,**kwargs)
posted @ 2023-02-04 17:12  李李大冒险  阅读(21)  评论(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.

作词 : 周有才

作曲 : 周有才

这是一首简单的歌

没有什么独特

试着代入我的心事

它那么幼稚

像个顽皮的孩子

多么可笑的心事

只剩我还在坚持

谁能看透我的眼睛

让我能够不再失明

我要记住你的样子

像鱼记住水的拥抱

像云在天空中停靠

夜晚的来到

也不会忘了阳光的温暖

我要忘了你的样子

像鱼忘了海的味道

放下所有梦和烦恼

却放不下回忆的乞讨

多么可笑的心事

只剩我还在坚持

谁能看透我的眼睛

让我能够不再失明

记住你的样子

像鱼记住水的拥抱

像云在天空中停靠

夜晚的来到

也不会忘了阳光的温暖

我要忘了你的样子

像鱼忘了海的味道

放下所有梦和烦恼

却放不下回忆的乞讨

只剩自己就好