2009-11-30 61 views
2

我基本上構建了一個非常小的表單。讓我們堅持django教程中給出的書籍/發佈者示例,並以此爲基礎。Django ModelForm,有一個外鍵作爲隱藏字段

我有一個用戶登錄到web應用程序,在這一點上他們可以做的第一件事是點擊一個發佈者。這位出版商隨後會保存他們的會話。在那之後,我帶他們去創建一本書。在那裏,我將數據庫中的發佈者ID嵌入到隱藏字段中。

當用戶提交的HTTP POST,我做這樣的事情:

mybookform = BookForm(request.POST) 
if mybookform.is_valid(): 
    abook = mybookform.save(commit=False) 
    abook.publisher_id = request.POST['publisher_id'] 
    mybookform.save() 

是的,有在這裏做了一些幼稚的事情,比如一味抓住PUBLISHER_ID並驗證它是否確實是一個真正的發佈者ID,除其他安全問題。我們暫時不關注這一點。

我的問題是,有沒有更好的方法來處理?雖然假設這個例子沒有物理意義,但在我的特定應用中,這個例子實際上是有道理的。問題是我得到一個ValueError異常,說publisher_id需要是一個Publisher實例。

現在我可以使用Publisher.objects.filter(id = ..)輕鬆地檢索發佈者實例並使用它。問題是,這是否真的有必要?我可以避免對數據庫進行額外的查詢,並以某種方式更新這個表單實例以更加「優雅」的方式嗎?

另外,是否有可能以某種方式將發佈者嵌入到隱藏字段中,以便我不需要執行mybookform.save(commit = False),而只需執行mybookform = BookForm(request.POST),然後執行mybookform.save ()立即?

回答

1

檢索發佈服務器的實例可防止可能引用完全無效的發佈服務器的客戶端更改。

對於第二個問題,是的,您可以通過overriding the field in the ModelForm將該字段作爲隱藏字段加上適當的表單字段,將widget設置爲HiddenInput

+0

感謝約翰。唯一的問題是,你的回答並不能幫助我弄清楚如何確保隱藏的輸入包含publisher_id的正確實例。 – randombits 2009-11-30 01:22:31

+0

Simon Willison已經就一些簽名的cookies進行了一些討論,更一般地說,包括在Django核心中的一般簽名(http://groups.google.com/group/django-developers/browse_thread/thread/133509246caf1d91)。您可以使用Simon的sign.py(http://github.com/simonw/django-openid/blob/master/django_openid/signed.py) – 2009-11-30 01:29:58

+0

nono加密簽名cookie或隱藏字段的值。我並不擔心加密cookies。我已經有了代碼。我的問題是,外鍵引用了發佈者,但它只能是一個發佈者。我不知道如何將隱藏的發佈者字段設置爲用戶登錄到應用程序時最初放入的實例的字段。 – randombits 2009-11-30 01:32:32

0

沒有更好的方法來做到這一點。

我會用get_object_or_404這個功能。

是的,你可以防止這種由用戶修改設置模型場editable=False

相關問題