如何对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
相关产品推荐
相关产品推荐

