2014-04-11 48 views
0

我想實現類似於Django inlineformsets的我自己的功能。我感興趣的是Django如何處理一個主對象的驗證和保存以及它內聯表單中的相關對象。django如何驗證並保存內聯表格

比方說,我有兩種型號:BlogEntryEntry有一個不爲空的Blog的外鍵。我希望能夠在一個地方創建博客和它的條目。這就是我將如何使用Django內聯表單來做到的:

blogform = BlogForm(request.POST) 
if blogform.is_valid(): 
    tmp = blogform.save(commit=False) 
    entriesform = EntryInlineFormset(request.POST, instance=tmp) 
    if entriesform.is_valid(): 
     entriesform.save() 
     blog.save() 

這是怎麼回事?如果沒有將博客保存到數據庫中,Django如何驗證條目?我想在Django代碼中找到它,但我無法找到他們實際執行此操作的地方。

我的感覺是他們創造了一個交易。他們保存blogform,如果entriesform無效,他們會回滾。但是,如果輸入表單有效,接下來會怎麼樣?博客實例是否保存?那麼如果save永遠不會被調用。

或者他們是否通過兩種方法跨越交易(is_validsave)?我認爲最好的做法是用一種方法開始交易,並以另一種方式結束交易。

回答

1

您可以在調用保存之前驗證它們。您可以將空白實例傳遞給父窗體和窗體集。

blog = Blog() 
blogform = BlogForm(request.POST, instance=blog) 
entriesform = EntryInlineFormset(request.POST, instance=blog) 
blog_valid = BlogForm.is_valid() 
entries_valid = entriesform.is_valid() 

if blog_valid and entries_valid: 
    ... save ... 

我單獨驗證表單並將結果保存到變量以避免短路。

+0

感謝Daniel的回答。這有一點幫助,但我可能對自己很不好解釋。你是否知道如果django'BaseInlineFormset'的實現能夠獲得博客ID(或者任何非空外鍵基本上),如果它需要驗證通過?我想知道內部,所以我可以在我的應用程序中實現類似的東西。 – davekr

+0

您可以舉例說明驗證需要FK嗎? 「Django」在formset中完全沒有這樣做:我期望你指的是admin中的行爲,這是在[ModelAdmin.changeform_view]中完成的(https://github.com/django/django/blob/主/ django的/了contrib /管理/ options.py#L1355)。 –

+0

是的,你是對的。在formset中沒有驗證FK。如果您嘗試保存它,它會引發一個'IntegrityError'。 'entriesform'只是保留對'blog'實例的引用,並且'blogform'保存後'entriesform'的引用具有id並且formset可以被保存。這是我想知道的,非常感謝! – davekr