Проверка ключей и типов значений в 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")
Вернуться на верх