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

如何对Django的JSONField进行预定义键与类型验证?

Django JSONField 结构化类型验证方案

Django 内置功能说明

Django 自带的 JSONField 仅会验证存储的数据是合法的 JSON 格式,没有内置针对预定义键和对应类型的验证功能——它只确保数据能序列化为 JSON,不会检查键的存在性或对应值的类型。

推荐解决方案

1. 模型 clean() 方法(无额外依赖)

适合简单验证场景,直接在模型中重写 clean() 方法,手动校验 dict_field 的结构和类型:

from django.db import models
from django.core.exceptions import ValidationError

class MetaData(models.Model):
    main = models.ForeignKey(YourRelatedModel, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    dict_field = models.JSONField()

    def clean(self):
        super().clean()
        data = self.dict_field

        # 校验必填键是否存在
        required_keys = ["key1", "key2"]
        missing_keys = [key for key in required_keys if key not in data]
        if missing_keys:
            raise ValidationError(f"缺少必填字段: {', '.join(missing_keys)}")
        
        # 校验key1类型为布尔值
        if not isinstance(data["key1"], bool):
            raise ValidationError("key1 必须是布尔类型")
        
        # 校验key2类型为整数
        if not isinstance(data["key2"], int):
            raise ValidationError("key2 必须是整数类型")
        
        # 校验key3(可选)类型为整数或不存在
        if "key3" in data and not isinstance(data["key3"], int):
            raise ValidationError("key3 必须是整数类型或不提供")

这种方式无需额外安装依赖,逻辑直观,适合简单的验证规则。

2. 使用 Pydantic(推荐复杂场景)

Pydantic 是 Python 生态中成熟的数据验证库,能高效处理复杂的类型和结构校验,步骤如下:

首先安装 Pydantic:

pip install pydantic

定义 Pydantic 验证模型:

from pydantic import BaseModel
from typing import Optional

class MetaDataSchema(BaseModel):
    key1: bool
    key2: int
    key3: Optional[int] = None

在 Django 模型的 clean() 方法中集成验证:

from django.db import models
from django.core.exceptions import ValidationError

class MetaData(models.Model):
    main = models.ForeignKey(YourRelatedModel, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    dict_field = models.JSONField()

    def clean(self):
        super().clean()
        try:
            # 用Pydantic模型校验数据
            MetaDataSchema(**self.dict_field)
        except Exception as e:
            raise ValidationError(f"dict_field 格式错误: {str(e)}")

如果需要复用验证逻辑,还可以自定义一个基于 Pydantic 的 JSONField:

from django.db.models import JSONField
from django.core.exceptions import ValidationError

class PydanticJSONField(JSONField):
    def __init__(self, schema_model, *args, **kwargs):
        self.schema_model = schema_model
        super().__init__(*args, **kwargs)

    def validate(self, value, model_instance):
        super().validate(value, model_instance)
        try:
            self.schema_model(**value)
        except Exception as e:
            raise ValidationError(f"数据格式不符合要求: {str(e)}")

# 使用自定义字段
class MetaData(models.Model):
    main = models.ForeignKey(YourRelatedModel, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    dict_field = PydanticJSONField(schema_model=MetaDataSchema)

3. 使用 Django 第三方库(django-json-schema-validator)

这个库专门为 Django JSONField 提供 JSON Schema 验证支持,适合习惯用 JSON Schema 定义规则的场景:

安装库:

pip install django-json-schema-validator

定义 JSON Schema 并使用字段:

from django.db import models
from django_json_schema_validator.fields import JSONSchemaValidatorField

# 定义JSON Schema规则
metadata_schema = {
    "type": "object",
    "properties": {
        "key1": {"type": "boolean"},
        "key2": {"type": "integer"},
        "key3": {"type": ["integer", "null"]}
    },
    "required": ["key1", "key2"]
}

class MetaData(models.Model):
    main = models.ForeignKey(YourRelatedModel, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    dict_field = JSONSchemaValidatorField(schema=metadata_schema)

内容的提问来源于stack exchange,提问作者Joseppy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 03:10:38