Как отобразить models.full_clean() ValidationError в админке django?

https://docs.djangoproject.com/en/4.0/ref/models/instances/#validating-objects

from django.core.exceptions import ValidationError
try:
    article.full_clean()
except ValidationError as e:
    # Do something based on the errors contained in e.message_dict.
    # Display them to a user, or handle them programmatically.
    pass

Тут говорят можно Показать их пользователю, а как отобразить ошибки в Admin?

Когда я ничего не делаю:

  • Когда в Settings.py Debug = True, всегда выдается ошибка ValidationError на странице /admin/xxx/xxx/xxx/xxx/change/ страница.
  • Когда Settings.py Debug = False, всегда выдается HTTP 500 страница.

Каков контекст этого кода? Django автоматически покажет ошибки для вас в админке при создании/редактировании объекта через админку. Вам не нужно вручную вызывать full_clean(), так как это сделает автоматически сгенерированная ModelForm из админки.

Я исправил эту ошибку самостоятельно.

Потому что админ django просто вызывает formsets.all_valid() для валидации в ModelAdmin._changeform_view().

ModelAdmin._changeform_view() использует transaction.atomic().

Когда formsets.all_valid(), удаляемые объекты не были зафиксированы.

Теперь предыдущее состояние - это экземпляр, который будет удален. Он не будет поднимать ValidationError, formsets.all_valid() будет return True.

Так ModelAdmin._changeform_view() будет вызывать from.instance.save() в foreach formsets.

На этот раз предыдущее состояние было изменено. Поэтому оно увеличит ValidationError.

Но ModelAdmin._changeform_view() не ожидал ValidationError в ModelAdmin.save_related(). он будет ожидать по django\core\handlers\exception.py и вызовет response_for_exception().

Я закрываю ModelAdmin._create_formsets() и заполняю previous_state все formsets.instance.

Замечание: когда вы получаете form, вы должны смотреть, какая модель не вызывает model.clean(), я использую form.changed_data для получения экземпляра.

Затем, когда ModelAdmin._create_formsets() вызовите formsets.all_valid(). Это будет return False, и raise ValidationError в вашей странице.

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