首页 > 编程语言 >反序列化类的校验部分源码解析-断言-drf之请求-drf之响应-视图组件介绍及两个视图基类-基于GenericAPIView的五个视图扩展类

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

时间:2023-02-04 19:34:03浏览次数:42  
标签:self 视图 序列化 data Response drf

目录

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

昨日内容回顾

# 1 序列化类的常用字段
	CharField
    IntegerField
    DecimalField
    DateTimeField
    BooleanField
    ListField
    DictField
    
# 2 字段参数
	-max_length  min_length 最大最小长度
    -max_value  min_value 最大最小值
    -required 表明该字段在反序列化时必须输入 默认True
    -default 反序列化时使用的默认值
    -read_only 只读  write_only 只写
    
# 3 定制序列化字段(改名字)
	-source这个字段参数
    -如果是表模型自己的字段 直接写
    -如果是关联字段 通过外键拿到
    
# 4 定制序列化字段(格式更丰富)
	-在序列化类中使用:SerializerMethodField 配合一个get_字段名的方法 方法返回什么 这个字段就是什么---> 这种字段以后不能用来做反序列化了
    -在表模型中使用 写方法的方式 方法返回什么 这个字段就是什么 序列化类中需要配合ListField DictField---> 这种字段以后不能用来做反序列化了
    	-方法可以包装成数据属性 也可以不(伪装)
        
# 5 反序列化校验四层
	-1 字段自己的校验规则 序列化类字段参数控制的
    -2 每个字段单独设置校验方法(了解)
    -3 局部钩子
    -4 全局钩子
    
# 6 ModelSerializer:继承自Serializer
	class BookSerializer(ModelSerializer):
        # 如果字段是映射过来的,也会把字段属性[反序列化校验规则],也会映射过来,有可能会校验失败,不能写入
        # 咱们重写这个字段,不加任何规则,取消掉它(意思就是先使用我们自己写的这个字段规则)
        name = serializer.CharField()
        class Meta:
            model=Author
            # fields="__all__"
            # 只要是序列化的字段和反序列化的字段,都要在这注册
            # 序列化的字段,可能不是表模型的字段,是咱自己写的方法
            # 序列化的字段,可能是使用SerializerMethodField,也要注册
            fields=['name','photo','gender','addr'...] 
            extra_kwargs={}  # 给字段类增加属性,read_only 和write_only用的多
            
		# 其他表中的字段,只要用到就要在上面注册
       gender=serializer.CharField()
       addr=serializer.CharField()
       局部钩子,全局钩子完全一样
       SerializerMethodField也一样
       create
       update
        
# 7 反序列化字段 一定要跟表模型的字段是对应的吗?
	不一定 随意写

今日内容概要

  • 1 反序列化类校验部分源码解析(了解)

  • 2 断言

  • 3 drf之请求

    • 3.1 Request能够解析前端传入的编码格式
    • 3.2 Request类有哪些属性和方法
  • 4 drf之响应

    • 4.1 Response能够响应的编码格式
    • 4.2 Response的源码属性和方法
  • 5 视图组件介绍及两个视图基类

    • 5.1 APIView+ModelSerializer+Response写五个接口
      • 5.1.1 视图类
      • 5.1.2 序列化类
      • 5.1.3 路由
  • 6 基于GenericAPIView+五个视图扩展类

    • 6.1 视图类
    • 6.2 序列化类
    • 6.3 路由

今日内容详细

1 反序列化类校验部分源码解析(了解)

# 反序列化校验 什么时候开始执行校验
	-视图类中执行到 ser.is_valid()就会执行校验 校验通过返回True 不通过返回False
    
# 入口:ser.is_valid() 是序列化类的对象 假设序列化类是BookSerializer---> 点is_vaild进入源码 找不到 找到父类BaseSerializer中有:
【raise_exception:先注意】
   def is_valid(self, *, raise_exception=False):
    
        if not hasattr(self, '_validated_data'):
            try:
                # self序列化类的对象,属性中没有_validated_data,一定会走这句【核心】
                self._validated_data = self.run_validation(self.initial_data)
            except ValidationError as exc:
                self._validated_data = {}
                self._errors = exc.detail
            else:
                self._errors = {}

        if self._errors and raise_exception:
            raise ValidationError(self.errors)

        return not bool(self._errors)
    # self._validated_data = self.run_validation(self.initial_data)
    核心---> self序列化类的对象
    	-切记一定不要按住ctrl键点击
        -真正的执行顺序是 从上往下 找不到 再往上
        -最终从Serializer类中找到了run_validation 而不是Field中的 run_validation
        
        
def run_validation(self, data=empty):
        # 字段自己的,validates方法
        (is_empty_value, data) = self.validate_empty_values(data)
        if is_empty_value:
            return data
        # 局部钩子----【局部钩子】
        value = self.to_internal_value(data)
        try:
            
            self.run_validators(value)
            # 全局钩子--》如果在BookSerializer中写了validate,优先走它,非常简单
            value = self.validate(value)
 
        except (ValidationError, DjangoValidationError) as exc:
            raise ValidationError(detail=as_serializer_error(exc))

        return value
    
# 局部钩子 self.to_internal_value(date)---> self是BookSerializer的对象 从根上找
     def to_internal_value(self, data):
        ret = OrderedDict()
        errors = OrderedDict()
        fields = self._writable_fields
        # fields写在序列化类中一个个字段类的对象
        for field in fields:
            # self BookSerializer的对象,反射validate_name
            validate_method = getattr(self, 'validate_' + field.field_name, None)
            try:
                # 在执行BookSerializer类中的validate_name方法,传入了要校验的数据
               validated_value = validate_method(validated_value)
            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

2 断言

# 源码中大量使用try和断言

# 关键字assert 有什么作用 断定你是xx 如果不是就抛异常

name = 'zpf'

if name == 'kjhl':
    print('对了')
else:
    print('错了')  # 错了
    raise Exception('名字不是zpf,不能往下走')  # Exception: 名字不是zpf,不能往下走
    
assert name=='zpf'  # 断定是 如果不是 就抛异常

3 def之请求

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

# 需求是该接口只能接收json格式 不能接收其他格式

# 方式一:在继承自APIView及其子类的视图类中配置(局部配置)
# 总共有三个:form rest_framework.parsers import JSONParser,FormParser,MultiPartParser
class BookView(APIView):
    parser_classes = [JSONParser,]
    
# 方式二:在配置文件中配置(影响所有 全局配置)
	-django有套默认配置 每个项目有个配置
    -drf有套默认配置 每个项目也有个配置---> 就在django的配置文件中
    REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES':[
            'rest_framework.parsers.JSONParser',
            'rest_framework.parsers.FormParser',
            'rest_framework.parsers.MultiPartParser',
        ],
    }
    
# 方式三:全局配置了1个 某个视图类想要三个 怎么配?
	-只需要在视图类 配置3个即可
    -因为:先从视图类自身找 找不到 去项目的drf配置中找 再找不到 去drf默认的配置找

3.2 Request类有哪些属性和方法(学过)

# 视图类方法中的request
	-data
    -__getattr__
    -query_params

4 drf之响应

4.1 Response能够响应的编码格式

# drf  是django的一个app 所有需要注册
# drf响应 如果使用浏览器和postman访问同一个接口 返回格式是不一样的
	-drf做了个判断 如果是浏览器 好看一点 如果是postman只要json数据
    
    
# 方式一:在视图类中写(局部配置)
	-两个响应类---> 找---> drf的配置文件中找---> 两个类
    -form 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',
        ],
    }
    
# 方式三:使用顺序(一般就用内置的即可)
	优先使用视图类中的配置 其次使用项目配置文件中的配置 最后使用内置的

4.2 Response的源码属性或方法

# drf 的Response 源码分析
	-from rest_framework.response import Response
    -视图类的方法返回时 return Response 走它的__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_200_OK)
        
    -tempate_name:了解即可 修改响应模板的样子 BrowsableAPIRenderer定死的样子 后期公司可以自己制定
    -headers:响应头 http响应的响应头
    	-原生的django 如何向响应头中加对象
        # 四件套 render redirect HttpResponse JsonResponse
        obj = HttpResponse('dddd')
        obj['xxc'] = 'yyc'
        return obj
    
    -content_type:响应编码格式 一般不动
    
# 重点:data status headers

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

# drf 视图 视图类 学过APIView drf的基类 drf提供的最顶层的类

# APIView跟之前的View区别
	-传入到视图方法中的是REST framework的Request对象 而不是Django的HttpRequest对象:
    -视图方法可以返回REST framework的Response对象
    -任何APIException异常都会被捕获到 并且处理成合适的响应信息
    -在进行dispatch()分发前 会对请求进行身份认证 权限检查 流量控制
    
# 两个视图基类
	APIView
    	-类属性:
        	renderer_classes  # 响应格式
            parser_classes  # 能够解析的请求格式
            authentication_classes  # 认证类
            throttle_classes  # 频率类
            permission_classes  # 权限类
        -基于APIView+ModelSerializer+Response写五个接口
        	-详见代码

5.1.1 视图类

from .models import Book
from .serializer import BookSerializer


class BookView(APIView):
    def get(self, request):
        books = Book.objects.all()
        ser = BookSerializer(instance=books, many=True)
        return Response(ser.data)

    def post(self, request):
        ser = BookSerializer(data=request.data)
        if ser.is_valid():
            ser.save()
            # 咱们现在只有ser序列化类的对象,但是咱们想要,新增的对象---》序列化成字典---》大前提,序列化类中的create方法一定要返回新增的对象
            return Response({'code': 100, 'msg': '新增成功', 'result': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})


class BookDetailView(APIView):
    def get(self, request, pk):
        books = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=books)
        return Response(ser.data)

    def put(self, request, pk):
        books = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(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):
        Book.objects.filter(pk=pk).delete()
        return Response({'code': 100, 'msg': '删除成功'})

5.1.2 序列化类

# ModelSerializer的使用
class BookSerializer(serializers.ModelSerializer):
    # 跟表有关联
    class Meta:
        model = Book
        field = ['name', 'price', 'publish_detail', 'zuthor_list' 'publish', 'authors']
        extra_kwargs = {
            'name': {'max_length': 8},
            'publish_detail': {'read_only': True},
            'author_list': {'read_only': True},
            'publish': {'write_only': True},
            'authors': {'write_only': True},
        }

5.1.3 路由

urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', views.BookView.as_view()),
    path('books/<int:pk>/', views.BookDetailView.as_view()),
]

6 基于GenericAPIView+5个视图扩展类

6.1 视图类

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

# 基于GenericAPIView+五个视图扩展类写接口


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

    def get(self, request):
        return self.list(request)

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

class BookDetailView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    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)

6.2 6.3 序列化类和路由

# 没有变化

标签:self,视图,序列化,data,Response,drf
From: https://www.cnblogs.com/zpf1107/p/17092197.html

相关文章

  • 【Django drf】视图类APIView之五层封装 ApiView的类属性 drf配置文件
    目录ApiView的类属性drf配置文件之查找顺序drf之请求APIView之请求相关配置drf之响应APIView之响应相关配置Response对象属性视图类序列化类路由基于GenericAPIview写五......
  • 【Rest Framework视图集ViewSet】
    一、与视图集配合使用的5个扩展类ListModelMixin:提供list(request,*args,**kwargs)方法快速实现列表视图,返回200状态码。该Mixin的list方法会对数据进行过滤和分页。Creat......
  • 【Rest Framework视图类GenericAPIView】
    一、继承关系APIView是RESTframework提供的所有视图的基类,继承自Django的View父类。GenericAPIView(rest_framework.generics.GenericAPIView)继承自APIVIew,增加了对于列表......
  • 【Rest Framework视图类GenericAPIView】
    一、继承关系APIView是RESTframework提供的所有视图的基类,继承自Django的View父类。GenericAPIView(rest_framework.generics.GenericAPIView)继承自APIVIew,增加了对于列表......
  • 反序列化类校验部分源码解析、断言、drf之请求、drf之响应、视图组件介绍及两个视图基
    反序列化类校验部分源码解析视图类中的ser.is_valid(),就会执行校验校验通过返回True不通过返回Flaseis_valid()入口:'''ser.is_valid()是序列化类的对象就假设序列化......
  • 为若依逆向工程创建mysql视图
    createviewview_jin_xiao_cun2asSELECTa.jiezhuan_prod_codeasprod_code,a.jiezhuan_prod_nameasprod_name,IFNULL(b.jiezhuan_count,0)asqichu_count,IFNULL......
  • drf之请求、响应
    目录断言drf之请求drf之响应断言断言使用关键字assert作用断言结果,如果不是就抛异常eg1:#断言name='rose'ifname=='kiki':print('你......
  • PHP反序列化字符逃逸 学习记录
    PHP反序列化字符逃逸的原理当开发者使用先将对象序列化,然后将对象中的字符进行过滤,最后再进行反序列化。这个时候就有可能会产生PHP反序列化字符逃逸的漏洞。详解PHP反......
  • drf-drf请求、响应、基于GenericAPIView+5个视图扩展类
    1.反序列化类校验部分源码分析(了解)1.当我们在视图类中生成一个序列化类对象ser,并且用ser.is_valid()是就会执行校验,校验通过返回True,不通过返回False。首先对象ser和序列......
  • DRF视图组件
    DRF视图组件 文章目录DRF视图组件一、视图视图继承关系二、2个视图基类1.APIViewAPIView与View示例小结2.GenericAPIView(通用视图类)1.......