Django Admin: JSONField по умолчанию пустое слово не будет сохраняться в админке - PullRequest
4 голосов
/ 13 марта 2019

в моей модели defn у меня есть

from django.contrib.postgres.fields import JSONField
.....
.......
.........

media_data=JSONField(default=dict)

Я создал администратора по умолчанию

Когда я пытаюсь сохранить, не касаясь поля, я получаю ошибку this field is required.

field is required

Это похоже на проблему проверки формы, потому что я могу программно сохранить экземпляр модели из кода без проблем.

Почему это происходит?
я что-то пропустил глупо?

Ответы [ 3 ]

2 голосов
/ 23 мая 2019
  1. Что происходит. когда погрузитесь в исходный код. мы можем увидеть следующий стек вызовов:
    1) form.is_valid() 
       ->form.full_clean()
        -->form._clean_fields()
         ---> self.cleand_data[name] = field.clean(value)
    2) field.clean(value)
        -> self.to_python(value)
        -> self.validate(value)

Когда вы смотрите в исходный код, вы можете обнаружить, что это в основном потому, что проверка empty_values.

# These values, if given to validate(), will trigger the self.required check.
EMPTY_VALUES = (None, '', [], (), {})

как видите, пустой dict {} как пустое значение для JSONField. так что это вызовет ошибку.

  1. Что мы можем сделать? Решением было бы настроить модели .JSONField и forms.JSONField, как показано ниже.

forms.py

from django.contrib.postgres import forms

class MyJSONField(forms.JSONField):
    empty_values = [None, "", [], ()]

дб / fields.py

class MyJSONField(JSONField):
    def formfield(self, **kwargs):
        from ..forms import MyJSONField

        return super().formfield(**{"form_class": MyJSONField, **kwargs})
0 голосов
/ 14 мая 2019

Это вызвало у меня проблемы в последнее время, хотя с django-mysql вместо postgres и в пользовательском ModelForm, а не с интерфейсом администратора.

В итоге я переопределил метод save() моей модели:

from django_mysql.models import JSONField

class yourModel(model):
    media_data=JSONField(default=dict, blank=True)

    def clean(self, *args, **kwargs):
        if self.media_data is None:
            self.media_data = "{}"

    def save(self, *args, **kwargs):
        self.clean()
        super().save(*args, **kwargs)
0 голосов
/ 13 марта 2019

В зависимости от ваших требований, используйте пустой и / или ноль.

media_data=JSONField(blank=True, null=True)

...