Как отобразить 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 в вашей странице.