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)(全局钩子)
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 []
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通