Мне просто интересно, если кто-нибудь знает, есть ли хорошая причина, почему джанго-орм не называет "full_clean" на модели, если он не сохраняется как часть модельной формы.
Обратите внимание, что full_clean() не будет вызываться автоматически при вызове метода save(). Вам нужно будет называть его вручную, если вы хотите выполнить одноэтапную проверку модели для своих созданных вручную моделей. django full clean doc
(ПРИМЕЧАНИЕ: котировка обновлена для Django 1.6... предыдущие django docs имели оговорку и о ModelForms.)
Есть ли веские причины, по которым люди не хотели бы этого поведения? Я думаю, если бы вы потратили время на добавление валидации модели, вы бы хотели, чтобы эта проверка выполнялась каждый раз, когда модель была сохранена.
Я знаю, как заставить все работать правильно, я просто ищу объяснения.
AFAIK, это связано с обратной совместимостью. Существуют также проблемы с ModelForms с исключенными полями, моделями со значениями по умолчанию, сигналами pre_save() и т.д.
Источники, на которые вы можете обратить внимание:
Из-за совместимости, учитывая, что в ядре django функция auto clean on save не включена.
Если мы начинаем новый проект и хотим, чтобы метод по умолчанию save
на модели мог автоматически очищаться, мы можем использовать следующий сигнал для очистки перед каждой сохраненной моделью.
from django.dispatch import receiver
from django.db.models.signals import pre_save, post_save
@receiver(pre_save)
def pre_save_handler(sender, instance, *args, **kwargs):
instance.full_clean()
Самый простой способ вызова метода full_clean
- это просто переопределить метод save
в model
:
def save(self, *args, **kwargs):
self.full_clean()
return super(YourModel, self).save(*args, **kwargs)
Вместо того, чтобы вставлять фрагмент кода, который объявляет приемник, мы можем использовать приложение как INSTALLED_APPS
в разделе settings.py
INSTALLED_APPS = [
# ...
'django_fullclean',
# your apps here,
]
До этого вам может потребоваться установить django-fullclean
с помощью PyPI:
pip install django-fullclean
pip install
приложение с четырьмя строками кода (проверьте исходный код ) вместо написания этих строк самостоятельно?
Если у вас есть модель, которую вы хотите обеспечить, по крайней мере, одно отношение FK, и вы не хотите использовать null=False
, потому что для этого требуется установка FK по умолчанию (который будет представлять собой данные мусора), лучший способ я Придумаем добавить пользовательские методы .clean()
и .save()
. .clean()
вызывает ошибку проверки, а .save()
вызывает чистоту. Таким образом, целостность обеспечивается как от форм, так и от другого кода вызова, командной строки и тестов. Без этого нет (AFAICT) никакого способа написать тест, который гарантирует, что модель имеет отношение FK к специально выбранной (не по умолчанию) другой модели.
class Payer(models.Model):
name = models.CharField(blank=True, max_length=100)
# Nullable, but will enforce FK in clean/save:
payer_group = models.ForeignKey(PayerGroup, null=True, blank=True,)
def clean(self):
# Ensure every Payer is in a PayerGroup (but only via forms)
if not self.payer_group:
raise ValidationError(
{'payer_group': 'Each Payer must belong to a PayerGroup.'})
def save(self, *args, **kwargs):
self.full_clean()
return super().save(*args, **kwargs)
def __str__(self):
return self.name
pre_save
и сделатьfull_clean
на всех пойманных моделях.