zoukankan      html  css  js  c++  java
  • DRF框架之反序列化校验

    DRF框架之反序列化校验

    上节补充

    内部类

    概念:将类部定义在一个类的内部,被定义的类就是内部类

    特点:内部类及内部类的所有名称空间,可以直接被外部访问的

    应用:通过内部类的名称空间。给外部类额外拓展一些特殊的属性(配置),典型的Meta内部类–配置类

    class Book(model.Model):
        class Meta:
            db_model = 'yellow books'#配置自定义表名
    class BookSerializer(serializers.ModelSerializer):
        class Meta:
            model = 'Book'	#配置序列化类的Model表
    

    DRF响应类:Response

    def __init__(self,data=None,status=None,template_name=None,headers=None,
                 exception=False,content_type=None):
        pass
    
    data:响应的数据 - 空、字符串、数字、列表、字段、布尔
    status:网络状态码
    template_name:drf说自己也可以支持前后台不分离返回页面,但是不能和data共存(不会涉及)
    headers:响应头(不用刻意去管)
    exception:是否是异常响应(如果是异常响应,可以赋值True,没什么用)
    content_type:响应的结果类型(如果是响应data,默认就是application/json,所有不用管)
    

    常见使用:

    Response(
        data={
        'status':0,
        'msg':'ok',
        'result':'正常数据'
    })
    
    Response(
    	data={
            'status':1,
            'msg':'客户端错误提示'},
        status=status.HTTP_400_BAD_REQUEST,
        exception=True
    )
    
    

    序列化基类控制的初始化参数

    def __init__(self,instance=None,data=empty,**kwargs):
        pass
    
    instance:是要被赋值对象的 - 对象类型书赋值给instance
    data:是要赋值数据的 - 请求来的数据赋值给data
    kwargs:内部有三个属性:many、partial、context
        many:操作的对象或数据,是单个的还是多个的
        partial:再修改需求时使用,可以将所有校验字段required校验规则设置为False
        context:用于视图类和序列化类直接传参使用
    

    常见使用:

    单查接口:

    UserModelSerializer(instance=user_obj)
    

    群查接口:

    UserModelSerializer(instance=user_query,many=True)
    

    增接口:

    UserModelSerializer(data=request.data)
    

    整体改接口:

    UserModelSerializer(instance=user_obj,data=request.data)
    

    局部改接口:

    UserModelSerializer(instance=user_obj,data=request.data,partial=True)
    

    删除接口:–用不到序列化

    反序列化

    view.py

    单查

    def get(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        if pk:  # 单查
            # 1)数据库交互拿到资源obj或资源objs
            # 2)数据序列化成可以返回给前台的json数据
            # 3)将json数据返回给前台
            try:
                obj = models.User.objects.get(pk=pk)
                serializer = serializers.UserModelSerializer(obj, many=False)
                return Response({
                    'status': 0,
                    'msg': 'ok',
                    'result': serializer.data
                })
            except:
                return Response(
                    data={
                        'status': 1,
                        'msg': 'pk error'
                    },
                    status=status.HTTP_400_BAD_REQUEST,  # 比直接写400更具有描述性
                    exception=True
                )
    
            else:  # 群查
                # 1)数据库交互拿到资源obj或资源objs
                # 2)数据序列化成可以返回给前台的json数据
                # 3)将json数据返回给前台
                queryset = models.User.objects.all()
                serializer = serializers.UserModelSerializer(queryset, many=True)
                return Response({
                    'status': 0,
                    'msg': 'ok',
                    'results': serializer.data
                })
    

    单增

    class UserAPIView(APIView):
        def post(self,request,*args,**kwargs):
            #单增
            #1)将前台请求的数据交给序列化类处理
            #2)序列化类执行校验方法,对前台提交的所有数据进行校验:校验失败就是异常返回,成功才能继续
            #3)序列化组件完成数据入库操作,得到入库对象
            #4)响应结果给前台
            serializer=serializers.UserModelSerializer(data=request.data)
            if serializer.is_valid():
                #校验成功=>入库=>正常响应
                obj = serializer.save()
                return Response({
                    'status':0,
                    'msg':'ok',
                    'result':'新增的那个对象'
                },status=status.HTTP_201_CREATED)
            else:
                #校验失败=>异常响应
                return Response({
                    'status':1,
                    'msg':serializer.errors,
                },status=status.HTTP_400_BAD_REQUEST)
    

    serializers.py

    标注:序列化=>后台到前台(读) | 反序列化=>前台到后台(写)

    1)不管是序列化还是反序列化字段,都必须在fields中进行声明,没有声明的不会参与任何过程(数据都会被丢弃)

    2)用read_only表示只读,用write_only 表示只写,不标注两者,代表可读可写

    3)

    1. 自定义只读字段,在model类中用@property声明,默认就是read_only

      @property
      def gender(self):
          return self.get_sex_display()
      

    2. 自定义只写字段,在serializer类中声明,必须手动明确write_only

      re_password = serializers.CharField(write_only=True)
      

      特殊:在serializer类中声明,没有明确write_only,是对model原有字段的覆盖,且可读可写

      password = serializers.CharField()
      

    4)用extra_kwargs来为写字段指定基础校验规则(了解)

    5)每一个写字段都可以用局部钩子 validate_字段(self,values)方法来定义校验规则,成功返回value,失败抛出exception.ValidationError(‘异常信息’)异常

    6)需要联合校验的写字段们,用validate(self,attrs)方法来定义校验规则,成功返回attrs,失败抛出exceptions.ValidationError({‘异常字段’:‘异常信息’}) 异常

    7)extra_kawrgs中一些重要的限制条件

    1. ‘required’:代表是否必须参与操作,有默认值或可以为空的字段,该值为False;反之该值为True;也可以手动修改值

    开发流程:

    1)在model类中自定义 读字段 ,在serializer类中自定义 写字段

    2)将model自带字段和所有自定义字段写在fields中,用write_only和read_only区别model自带字段

    3)可以写基础校验规则,也可以省略

    4)制定局部及全局钩子

    我把月亮戳到天上 天就是我的 我把脚踩入地里 地就是我的 我亲吻你 你就是我的
  • 相关阅读:
    31天重构学习笔记21. 合并继承
    31天重构学习笔记15. 移除重复内容
    31天重构学习笔记22. 分解方法
    31天重构学习笔记18. 使用条件判断代替异常
    31天重构学习笔记19. 提取工厂类
    31天重构学习笔记24. 分解复杂判断
    31天重构学习笔记17. 提取父类
    大型项目的发布部署:第一章:发布部署流程
    HDU 2036 改革春风吹满地 数学题
    HDU 2051 Bitset
  • 原文地址:https://www.cnblogs.com/zhulipeng-1998/p/12863867.html
Copyright © 2011-2022 走看看