Удостоверение того, что значения полей Django JSONField являются словарями

Можно ли как-то потребовать, чтобы Django JSONField хранил только словарные значения? И выбрасывал ошибку при скалярных значениях.

Например, я хочу, чтобы следующие значения были действительными:

{}
{"a": 1}
{"a": 1, "b": 2}

И я хочу, чтобы следующие значения были недействительными:

"hello world"
True
1

JSONField в настоящее время принимает все эти значения, что имеет смысл, поскольку все они являются корректным json. Но я хочу изменить это поведение.

В идеале я хочу обеспечить это на уровне базы данных, чтобы такие операции, как массовые вставки, были защищены. Но буду рад сделать это на уровне Django, если это будет лучшим / простым решением.

Я думаю, что можно разработать ограничение для этого, хотя я бы тщательно протестировал это, чтобы убедиться, что все работает так, как вы ожидаете при массовых операциях. В документации есть примечание именно о JSONField:

Ограничения, содержащие JSONField, могут не вызывать ошибок валидации, так как преобразования ключей, индексов и путей имеют множество специфических для базы данных предостережений. Это может быть полностью поддержано позже.

Вы всегда должны проверять, что в логере django.db.models нет сообщений типа "Got a database error calling check() on ...", чтобы убедиться, что валидация прошла правильно.

При этом я думаю, что подобное ограничение может сработать.

class YourModel(models.Model):
    ...

    class Meta:
        constraints = (
            models.CheckConstraint(
                check=models.Q(json_field__startswith="{", lead__isnull=False),
                name="only_single_objects_allowed",
                violation_error_message="Only singular objects are allowed.",
            ),
        )

Я не уверен, что startswith будет работать для JSONField. Глядя на исходный текст, я не вижу причин для этого, но сам я это не проверял.

Вернуться на верх