在Django中保存嵌套表单

时间:2012-03-29 13:12:39

标签: django validation django-models django-forms

我有一个奇怪的问题。我正在尝试验证通过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记录的ID。

您是否知道如何设置已验证的外键?未保存的表单,所以我可以安全地将其保存到数据库中?

2 个答案:

答案 0 :(得分:6)

您已从book中排除AuthorForm,因此Django并不关心cleaned_data['book_id']的价值是什么 - 它只会忽略它。

相反,您需要直接在未保存的作者实例上设置book属性:

    book = book_form.save()
    author = author.form.save(commit=False)
    author.book = book
    author.save()

答案 1 :(得分:3)

你可以尝试:

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()