You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 23:57:03