2012-03-29 63 views
5

我有一個奇怪的問題。我試圖驗證通過POST請求發送的一個表單,而這個表單實際上是建立在四個模型的基礎上的。在Django中保存嵌套表格

這個想法是驗證所有表單,然後按照適當的順序相應地保存它們,根據最近保存的模型實例分配外鍵。

當我嘗試將值分配給通過form.is_valid()調用正確驗證的模型的外鍵時,會出現問題。它拋出一個IntegrityError,說這個特定的外鍵「可能不是NULL」。

下面請找出應該給你的想法的代碼我在做什麼:

模型&形式defitinions:

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。

你有什麼想法我怎麼能設置外鍵已驗證&未保存的表單,所以我可以安全地將其保存到數據庫中?

回答

6

您已經排除AuthorFormbook,所以Django不關心的cleaned_data['book_id']值是 - 它會忽略它。

相反,你需要的書財產直接在未保存的作者實例設置:

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

它幫助,謝謝。 – Tadeck 2012-03-29 13:59:24

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