1

假設我有一個運行庫存系統的人員。每個人都有一些汽車,每輛汽車都有很多零件(數千個,我們假設)。Django:多對一的字段和數據完整性

一個人,Bob,使用Django表單來創建一個Car。現在,鮑勃去創建一些零件。只有在形式層面上,Django知道這些部件屬於某個特定的汽車,並且Parts.ForeignKey(Car)字段應該只有一個特定的汽車作爲選擇。在創建零件時,您必須弄亂表單的構造函數或類似物,才能將汽車的選擇限制爲僅由鮑勃擁有的汽車。

在表單級別強制執行此所有權似乎並不合適或安全。首先,除了車主外,其他用戶的汽車似乎都不可進入;目前,只有固體形式編程才能阻止任何人查看任何其他人的汽車!其次,通過以這種方式修改構造函數來處理這個問題似乎是草率的。你們怎麼看待這個問題,並且有什麼辦法可以實施?

回答

1

首先,這應該發生在你知道誰是當前用戶的級別上。 在Django theres沒有什麼像全局的request.user,所以你需要檢查這個地方你有一個請求對象或傳遞它作爲一個paremeter。

實現您要求的一種方法是使用自定義管理器。對於Car類可以使用

class CarManager(models.Manager): 
    def for_user(self, user): 
     return super(CarManager, self).get_query_set().filter(creator=user) 

您可能還想覆蓋默認管理器,它是默認方法,只允許使用此方法。

對於第二部分,如果您不喜歡它,則不需要修改構造函數。但修改它們可以確保您不會在沒有記錄用戶的情況下創建表單。另一種方法是使用ModelChoiceField,並覆蓋它在視圖的查詢集ATTR:

form.car.queryset = Car.objects.for_user(request.user) 

但這種方法很容易出錯。你應該sitil修改窗體構造函數,如下所示:

class PartForm(forms.ModelForm): 
    def __init__(self,user,*args,**kwargs): 
     super (PartForm,self).__init__(*args,**kwargs) 
     self.fields['car'].queryset = Car.objects.for_user(user) 

希望這會有所幫助。