• day 73


    day 73

    1. ModelSerializer类;模型序列化类 - 核心类

      1. 单表;

        1. 序列化类继承ModelSerializer,所以需要在配置类Meta中进行配置

          class UserModelSerializer(serializers.ModelSerializer):
          		class Meta:
          
        2. model配置:绑定序列化相关的model表

          model = models.User
          
        3. fields配置;采用插拔式,设置所有参与序列化与反序列化字段

          fields = ('username', 'gender', 'icon', 'password', 'sex', 're_password')
          # 所有参与序列化与反序列化的(系统或自定义)字段都要到内部进行注册
          
        4. extra_kwargs配置;

          extra_kwargs = {
            'username': {  # 系统字段不设置read_only和write_only,默认都参加
              'min_length': 3,  # 配置简单的校验信息
              'max_length': 10,
              'error_messages': {  # 配置不符合校验规则的返回信息
                'min_length': '太短',
                'max_length': '太长'
              }
            },
            'gender': {
              'read_only': True,  # 自定义的序列化字段默认就是read_only,且不能修改,可以省略
            },
            'password': {
              'write_only': True,  # 配置为只写,反序列化,用于入库但不给客户端展示的字段
            },
            'sex': {  # 像sex有默认值的字段,为选填字段('required': True可以将其变为必填字段)
              'write_only': True,
              # 'required': True
            }
          }
          
        5. 自定义反序列化字段

          re_password = serializers.CharField(min_length=3, max_length=16, write_only=True)
          # 自定义反序列化字段一般不需要返回给前端,要设置 write_only = True
          
        6. 自定义序列化字段(推荐使用)

          # 在model类中配置
              @property  # 序列化是通过反射的方法获取值
              def gender(self):
                  return self.get_sex_display()
          
        7. 局部校验钩子函数validate_字段名(self,字段值value),所有字段都可以设置局部校验。规则;成功直接返回value,失败则抛出异常ValidationError('错误信息')

          		def validate_username(self, value):
                  if 'g' in value.lower():
                      raise serializers.ValidationError('名字中不能有g')
                  return value
          
        8. 全局校验钩子函数validate(self, 所有字段字典attrs),可以在内部进行需要多字段参与的校验。规则成功直接返回attrs,失败则抛出异常ValidationError({'异常字段': '错误信息'})

              def validate(self, attrs):
                  password = attrs.get('password')
                  re_password = attrs.pop('re_password')
                  if password != re_password:
                      raise serializers.ValidationError({'re_password': '两次密码不一致'})
                  return attrs
          
        9. ModelSerializer内部写好了create和update方法,所以不需要重写

    2. ListSerializer类;群操作序列化类 - 辅助类

      1. 重点;辅助完成单表多表群增群改操作
      2. 需要自定义辅助类继承ListSerializer
      3. 重写update方法,(ListSerializer没有写update方法,有create方法)
      class BookListSerializer(serializers.ListSerializer):
        def update(self, instance_list, validated_data_list):
          return [
            self.child.update(instance_list[index], attrs) for index, attrs in enumerate(validated_data_list)  # self.child 为自定义的序列化模型类(BookModelSerializer)
          ]
      

    01单表操作

    class UserV3APIView(APIView):
        # 单查群查
        def get(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            if pk:
              # 获取数据
                user_obj = models.User.objects.filter(is_delete=False, pk=pk).first()
                if not user_obj:
                    return Response({
                        'status': 1,
                        'msg': 'pk error',
                    }, status=400)
    						# 将数据交给序列化类处理
                user_ser = serializers.UserModelSerializer(user_obj, many=False)
                return Response({
                    'status': 0,
                    'msg': 'ok',
                    'results': user_ser.data  # 将序列化好的数据取出
                })
            else:
                user_query = models.User.objects.filter(is_delete=False).all()
    
                user_ser = serializers.UserModelSerializer(user_query, many=True)
    
                return Response({
                    'status': 0,
                    'msg': 'ok',
                    'results': user_ser.data
                })
    
        # 单增
        def post(self, request, *args, **kwargs):
            user_ser = serializers.UserModelSerializer(data=request.data)
            if user_ser.is_valid():
                # 入库
                user_obj = user_ser.save()
                return Response({
                    'status': 0,
                    'msg': 'ok',
                    'results': serializers.UserModelSerializer(user_obj).data
                })
            else:
                return Response({
                    'status': 1,
                    'msg': user_ser.errors,
                })
    
    

    02多表操作

    1. 基表;为抽象表,专门用来继承的,为表提供公有字段的,自身不会在数据库中创建

      class BaseModel(models.Model):
        class Meta:
          abstract = True
      
    2. 断关联表关系

      1. 不会影响连表查询操作
      2. 会提升增删改的效率
      3. 易于后期数据库表的重构
      4. 缺点在于,数据库本身没有连表检测,容易出现脏数据,需要通过严格的逻辑避免脏数据的产生(必要时管理脏数据)
        1. A依赖于B,先插入A,该记录对应的B记录没有产生,在没有关联的情况下该数据可以产生,该数据就是脏数据
        2. 接着再将B数据添加,脏数据就得到了处理,反过来先产生B再产生A,更符合逻辑,通过逻辑将表进行关联
        3. 连表查询,不会有任何异常
      5. related_name 在外键中,设置外键反向查询的字段名,正向找字段名,反向找related_name值
      6. on_delete在外键中必须设置,表示级联关系,在Django 1.X 下系统默认提供值为 models.CASCADE,Django 2.X 下必须手动声明,
        1. CASCADE;默认值,级联
        2. DO_NOTHING;外键不会被级联,假设A表依赖于B表,删除B表,A表的外键字段不做任何处理
        3. SET_DEFAULT;假设A表依赖于B表,B记录删除,A表的外键字段设置为default属性设置的值,必须配合default使用
        4. SET_NULL;假设A表依赖于B表,B记录删除,A表的外键字段设置为null,所以必须配合null = True使用
      7. db_constraint在外键中控制表关联,默认为True表示关联,设施False表示断开关联(该字段只能给ForeignKey)
    3. 子查询

      1. 外键字段默认显示的是外键值(int类型)
  • 相关阅读:
    6.Docker中上传镜像到docker hub中
    altermanager使用报错
    Grafana官方和社区提供的dashboard
    什么是 云原生?
    prometheus被OOM杀死
    新版GRANAFA K8S插件 K8S NODE 图表不显示问题解决方法
    python2和python3的不同
    一次使用Python连接数据库生成二维码并安装为windows服务的工作任务
    Python连接oracle
    numpy.ndarray的赋值操作
  • 原文地址:https://www.cnblogs.com/luocongyu/p/12120404.html
Copyright © 2020-2023  润新知