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类型)
posted @ 2019-12-30 16:33  🍞面包🍞  阅读(95)  评论(0编辑  收藏  举报