Проверка нескольких внешних ключей при сохранении формы ModelForm

Пояснение:

У меня есть модель, которая имеет два внешних ключа:

class Book(models.Model):
    name = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=CASCADE)
    created_by = models.ForeignKey(User, blank=True, null=True, on_delete=CASCADE)

У меня есть модельная форма для этого:

class BookForm(modelForm):
    class Meta:
        model = Book
        exclude = ('author', 'created_by',)

В моей бизнес-логике я хочу сохранить нового автора и книгу с ним в одном представлении, а created_by в некоторых случаях может быть null. Поэтому, прежде чем сохранить экземпляр BookForm, я сначала создам автора. Итак, предположим, что я создал автора, тогда для сохранения книги я сделаю следующее:

f = BookForm(post_data)
if form.is_valid():
    instance = f.save(commit=False)
    instance.author = author
    instance.created_by = user
    instance.save()

То, что я сделал до сих пор, работает нормально, но поля внешнего ключа не являются частью валидации. Как видно из класса модели, поле author является обязательным, а поле created_by - необязательным. Поэтому, если я хочу добавить некоторые валидации для них, я должен добавить их явно, настроив метод is_valid(), или добавив некоторые if условия перед instance.author = author.

Вопрос:

Большая картина заключается в том, что у меня есть модель с гораздо большим количеством внешних ключей; некоторые из них являются обязательными, а другие - нет. Поэтому, используя тот же подход, что и выше, я должен добавить пользовательскую валидацию для каждого FK в явном виде, что я считаю дублированием и нечистотами, поскольку валидация этих полей FK определена в классе моей модели

Итак, какова наилучшая практика для автоматической проверки множественных внешних ключей при сохранении, проверяя проверку моделей напрямую и не упоминая каждый FK по одному?

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

Django предоставляет метод model.full_clean(), который выполняет все шаги по проверке модели.

Вам придется вызвать метод вручную, поскольку метод save() не вызывает никакого метода очистки модели.

См. документацию здесь.

Например,

f = BookForm(post_data)
if form.is_valid():
    instance = f.save(commit=False)
    instance.author = author
    instance.created_by = user
    try:
        instance.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
    instance.save()

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