DRF框架--Python基于DRF的Serializer实现字段验证及序列化,及额外参数传递

在序列化类文件serializer.py中是可以做字段校验的

字段校验有三种:

1.参数校验

--定义在fileds中的参数,如required,max_length,min_length.....等等,对传入数据的各个字段本身的属性进行校验

2.函数校验

--在fileds中添加到字段validators=[ ]参数的列表中

复制代码
    name = serializers.CharField(max_length=10,
                                 label="项目名称",
                                 help_text="项目名称",
                                 min_length=3,
                                 validators=[
                                     validators.UniqueValidator(queryset=Projects.objects.all(),message="项目名name已存在"),
                                     check_name,
                                 ],
                                 error_messages={"required": "该字段必传", "max_length": "长度不能操作10个字节",
                                                   "min_length": "长度不能少于3个字节"})
复制代码

validators中自带的验证器:

--UniqueValidator

用于验证(唯一)unique=True的字段,常用参数:

  • queryset: required,用于明确验证唯一性集合,必须设置
  • message:当验证失败时的提示信息
from rest_framework.validators import UniqueValidator

slug = SlugField(
    max_length=100,
    validators=[UniqueValidator(queryset=BlogPost.objects.all())]
)

--UniqueTogetherValidator

  • queryset:required,用于明确验证唯一性集合,必须设置
  • fields: required,字段列表或者元组,字段必须是序列化类中存在的字段
  • message:当验证失败时的提示信息
  • UniqueTogetherValidator有一个隐性要求就是验证的字段必须要提供值,除非设置了一个默认值
复制代码
from rest_framework.validators import UniqueTogetherValidator

class ExampleSerializer(serializers.Serializer):
    class Meta:
        validators = [
            UniqueTogetherValidator(
                queryset=ToDoItem.objects.all(),
                fields=('list', 'position')
            )
        ]
复制代码

3.局部钩子和全局钩子校验

  --局部钩子校验单字段(单字段校验validate_fieldName)

  --全局钩子多字段联合校验(比如两次密码输入是否一致等)

局部钩子:

    def validate_name(self, value):  #固定写法validate_+要校验多字段名
        if '测试' in value:
            raise serializers.ValidationError("项目名称中不能包含测试")
        return value  # 要记住将value返回

全局钩子:

 def validate(self, attrs):  #多字段联合校验
     if len(attrs["name"]) == 8 and "测试" not in attrs["tester"]:
         raise serializers.ValidationError("项目名称长度不为8并且tester中不包含测试")
     return attrs

 

反序列化时校验顺序: 字段1的参数校验,字段1的局部钩子,字段2的参数校验,字段2的局部钩子,...最后执行全局钩子

1、先校验定义在filed中的参数
2、校验filed中的validators
3、再校验validate_fieldName函数(局部钩子)
4、最后校验多字段联合校验 validate(self,attrs)(全局钩子)

 

serializer额外参数传递

通过context字段可以达到向serializer类中传递参数的问题

示例:将data中id的值作为参数传递到serializer类中

serializer = DeviceByTypeSerializer(device_type, many=True, context={'id': data.id})

而在serializer中调用示例代码如下: 序列化实例 context['id']

复制代码
class DeviceByTypeSerializer(serializers.ModelSerializer):
    devices = serializers.SerializerMethodField('get_pl_ds')

    class Meta:
        model = DeviceType
        fields = ('name', 'devices')

    def get_pl_ds(self, obj):
        try:
            pl_ds_queryset = obj.devices.filter(pl_belong=self.context['id'])
            if pl_ds_queryset.exists():
                print(pl_ds_queryset)
                serializer = DeviceSerializer(instance=pl_ds_queryset, context=self.context, many=True)
                return serializer.data
            else:
                print(pl_ds_queryset)
                return []
        except Exception as e:
            print(e)
            return []
复制代码

 

posted @   EricYJChung  阅读(637)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示