Сохранение вложенных форм в Django - PullRequest
5 голосов
/ 29 марта 2012

У меня странная проблема.Я пытаюсь проверить одну форму, отправленную с помощью запроса POST, и эта форма фактически основана на четырех моделях.

Идея состоит в том, чтобы проверить все формы и затем сохранить их соответствующим образом в соответствующем порядке,назначение внешних ключей на основе недавно сохраненных экземпляров модели.

Проблема возникает, когда я пытаюсь присвоить значение внешнему ключу модели, который был надлежащим образом проверен с помощью вызова form.is_valid().Однако он выдает IntegrityError о том, что этот конкретный внешний ключ " не может быть NULL ".

Ниже приведен код, который должен дать вам представление о том, что я делаю:

Определения моделей и форм:

class Author(models.Model):
    name = models.CharField(blank=False, max_length=150)
    book = models.OneToOneField('Book')  # its important, one author has one book

class Book(models.Model):
    name = models.CharField(blank=False, max_length=150)

class AuthorForm(ModelForm):
    class Meta:
        model = Author
        exclude = ('book',)

class BookForm(ModelForm):
    class Meta:
        model = Book

В одном из представлений:

if request.method == "POST":
    author_form = AuthorForm(request.POST, prefix='author')
    book_form = BookForm(request.POST, prefix='book')
    if author_form.is_valid() and book_form.is_valid():
        book = book_form.save()
        author_form.cleaned_data['book_id'] = book.id
        author.form.save()  # Error!

Во время author_form.save() Я получаю ошибку, подобную этой:

IntegrityError at /api/my_method
myapp_author.book_id may not be NULL

Я полностью уверен, что book.id - это целое число (int, я проверил его) с идентификатором недавно сохраненной Book записи.

У вас есть идеи, как я могустановить внешний ключ с проверенной и несохраненной формой, чтобы я мог безопасно сохранить его в базе данных?

Ответы [ 2 ]

6 голосов
/ 29 марта 2012

Вы исключили book из AuthorForm, поэтому Django не волнует, каково значение cleaned_data['book_id'] - оно просто проигнорирует его.

Вместо этого вам нужно установитьсвойство книги непосредственно в несохраненном экземпляре автора:

    book = book_form.save()
    author = author.form.save(commit=False)
    author.book = book
    author.save()
3 голосов
/ 29 марта 2012

Вы можете попробовать:

if author_form.is_valid() and book_form.is_valid():
    book = book_form.save()
    author = author_form.save(commit=False)
    author.book = book
    author.save()
...