如何为PrimaryKeyRelatedField序列化器添加required等校验规则
实现方案
1. 基础校验规则添加
你自定义的WorkLocationField继承自DRF原生的PrimaryKeyRelatedField,原生支持所有通用校验参数,直接在字段声明时传入即可,比如required=True、allow_null=False、自定义error_messages等参数都可以直接使用。
2. 嵌套JSON数据校验实现
原有代码直接将传入的字典解包执行查询/创建操作,没有做字段合法性校验,容易触发报错或者非法数据入库,我们可以新增一个专用的序列化器处理嵌套数据的校验逻辑,修改后的完整代码如下:
from rest_framework import serializers from .models import WorkLocation, JobPost # 新增用于校验嵌套工作地点数据的序列化器 class WorkLocationValidatorSerializer(serializers.ModelSerializer): class Meta: model = WorkLocation fields = ["city", "latitude", "longtitude"] # 限制仅允许这三个字段传入 class WorkLocationField(serializers.PrimaryKeyRelatedField): queryset = WorkLocation.objects.all() def to_internal_value(self, data): # 判断传入的是否为嵌套字典格式 if isinstance(data, dict): # 调用序列化器做校验,校验失败自动抛出错误 validator = WorkLocationValidatorSerializer(data=data) validator.is_valid(raise_exception=True) # 校验通过后再执行查询/创建逻辑 location, created = WorkLocation.objects.get_or_create(**validator.validated_data) data = location.pk return super().to_internal_value(data) class JobPostSerializer(serializers.ModelSerializer): # 直接传入你需要的校验规则即可 work_location = WorkLocationField( required=True, error_messages={ "required": "工作地点为必填项", "does_not_exist": "传入的工作地点ID不存在" } ) class Meta: model = JobPost fields = "__all__"
实现效果
- 基础校验生效:请求不传
work_location字段时,会直接返回必填项错误 - 嵌套数据校验生效:传入的
work_location字典缺少必填字段、字段类型不匹配、字段长度超出限制时,都会返回对应的字段级校验错误 - 兼容原有逻辑:如果传入的是数字类型的工作地点ID,会保持原有逻辑校验ID是否合法存在
内容的提问来源于stack exchange,提问作者surya raj
相关产品推荐
相关产品推荐

