2011-10-10 53 views
0

想象一下,我們正在開發一個消息系統,並且每個Message都有一個用於sender的外鍵。將任意數據添加到ModelForm的最簡單方法是什麼?

我們使用ModelForm s,並有MessageForm推斷其領域從Message
當然,我們不希望用戶能夠通過發佈不同的發件人ID來欺騙sender

因此,我們必須從ModelForm中排除sender,並從session開始填寫。

在哪裏以及如何將任意數據分配到ModelForm字段?

在我的例子中,我可能想要訪問session,所以我們也需要訪問request
這是否意味着代碼必須位於視圖中,在表單創建之後?

我們如何從代碼分配表單域並確保它覆蓋POST數據?

(當然,這個例子是非常虛構的,是這裏只是爲了說明這個問題。)

回答

1

您只需排除它,你必須再加工的形式來看時做到:

obj = form.save(commit=False) 
obj.sender = request.user 
obj.save() 

或者,您可以在表單的保存方法做到這一點;爲此,您需要在表單中暫時保存請求對象。像下面這樣:

class MyForm(forms.ModelForm): 
    def __init__(self, request, *args, **kwargs): 
    self._request = request 
    super(MyForm, self).__init__(*args, **kwargs) 

    def save(self, commit=False): 
    obj = super(MyForm, self).save(commit=False) 
    obj.sender = self._request.user 
    if commit: 
     obj.save() 

    return obj 

我偏向於第二種方法我自己,因爲它有助於封裝關於該模型的邏輯,它是在一個整潔的地方的數據。

+0

這是一個有價值的補充,我欣賞樣本。謝謝。 –

+0

你能解釋一下在這種情況下'commit = False'是什麼意思? –

+1

@Dan Abramov:'commit = False'是一個可以傳遞給'ModelForm.save()'方法的參數,它將阻止保存底層模型對象。而是創建模型(填充相應的字段)並返回。然後您可以設置其他模型字段並保存模型。 –

1

剛從ModelForm排除sender場,當你實例中的POST端點的視圖對象(保存之前),請確保使用適當的會話或用戶ID填充sender字段。

當您排除該字段時,無法將該字段添加到發佈數據[1],因此用戶無法欺騙它。

[1]使用JavaScript,理論上可以添加&sender=someSenderId,但在您看來,您無需查找發件人字段。它不會被序列化爲ModelForm對象。

+0

來自.NET的背景,我只是沒有意識到它可以*那*簡單。 –

相關問題