Проверка ключей и типов значений в Django .JSONFields
Заявление о проблеме
У меня есть модель Django, содержащая JSONField:
class DataModel(models.Model):
dict_field = models.JSONField()
Как я могу проверить входы этого JSONField так, чтобы оно принимало только предопределенный список ключей и связанных с ними типов, как показано ниже:
"key1": bool
"key2": int
"key3": Optional[int]
Моя попытка
Я попытался решить эту проблему с помощью Pydantic, определив класс:
class DictModel(pydantic.BaseModel):
key1: bool
key2: int
key3: Optional[int]
Но я не смог найти способ передать эту схему в мою модель Django. Есть ли в django что-то встроенное для решения такого рода проблем?
Django не имеет встроенной поддержки для проверки ключей и значений JSONField описанным вами способом. Однако вы можете использовать пользовательский валидатор для достижения этой цели.
Сначала определите функцию, которая принимает значение поля JSONField и возвращает True, если значение действительно, и False в противном случае. Эта функция должна проверять ключи и связанные с ними типы на соответствие предопределенному списку разрешенных ключей и типов. Вот пример:
def validate_json_field(value):
expected_keys = {
"key1": bool,
"key2": int,
"key3": Optional[int]
}
for key, expected_type in expected_keys.items():
if key not in value:
return False
if not isinstance(value[key], expected_type):
return False
return True
Далее, вы можете использовать эту функцию в качестве валидатора для вашего JSONField, добавив ее в опцию валидаторов при определении поля:
class DataModel(models.Model):
dict_field = models.JSONField(validators=[validate_json_field])
Это гарантирует, что поле dict_field принимает только те значения, которые имеют правильные ключи и связанные с ними типы. Обратите внимание, что при этом не будут проверяться значения необязательного поля key3; вам нужно будет добавить дополнительную логику в функцию проверки для обработки этого случая.
Вот решение
Вы можете использовать Foreign Key Field
в модели django.class Keys(models.Model):
key1 = models.BooleanField(blank=False) #bool
key2 = models.PositiveIntegerField(blank=False) #int
key3 = models.PositiveIntegerField(blank=True) #int[optional]
class DataModel(models.Model):
dict_field = models.ForeignKey("Keys", on_delete=models.SET_NULL, null=True, blank=False, related_name="data")