2013-12-09 94 views
2

我有模型字段,如下圖所示: -使用屬性來修改模型字段的Django

user=models.ForeignKey(CustomUser, null=True) 
_corporate = models.CharField(max_length=10, null=True, db_column='corporate') 
def set_corporate(self,value): 
    if self.user.corporateuser_set.all(): 
     self._corporate = self.user.corporateuser_set.values_list('company', flat=True) 
corporate= property(set_corporate) 

不知何故,set_corporate沒有被評估並且因此_企業字段不被更新。

那麼我該怎麼做才能使它工作?這裏最好的方法是什麼?

我有另一個模型(CorporateUser)與用戶模型的一對多關係,只是爲了清晰我的問題。

回答

3

你在這麼多方面做錯了。

首先,屬性在Python這樣使用:

class A: 
    @property 
    def foo(self): 
     return self._foo 

    @foo.setter 
    def foo(self, value): 
     self._foo = value 

或者這樣說:

class A: 
    def get_foo(self): 
     return self._foo 

    def set_foo(self, value): 
     self._foo = value 

    foo = property(get_foo, set_foo) 

注意值是如何傳遞給制定者。它不應該像你那樣在那裏計算。如果您需要自動更新企業價值,那麼您不需要財產,您應該覆蓋模型.save()方法或聆聽它的pre_save信號並在那裏更新字段。

其次,你不應該有條件地設置setter。 Setter應該始終將屬性設置爲傳遞的值。就像這樣:

def set_corporate(self, value): 
    # If the list is empty then corporate becomes empty 
    self._corporate = \ 
     self.user.corporateuser_set.values_list('company', flat=True) 

通過違反這條規則,你將造成悲痛:

obj.corporate = 'hi' 
# obj.corporate is now 'hi' 
obj.corporate = '' 
# obj.corporate is still 'hi'. WTF? 

第三,你不應該分配給listCharField。這應該如何工作?它可能會將其串聯起來。

第四,你甚至沒有分配一個列表,你正在分配查詢集,這是更糟。

第五,你在兩行中執行兩次基本相同的數據庫請求。檢查的有效途徑,如果是空的,然後分配是通過重用相同的查詢集:

corporates = self.user.corporateuser_set.values_list('company', flat=True) 
if corporates: 
    # Stringify it explicitly and our way 
    self._corporate = ','.join(corporates) 
+0

'違反這條規則你會引起悲傷:'什麼 規則? – user2454305

+0

安裝員應無條件設置。 – Suor

+0

爲了您的解釋,我接受您的答案。它很詳細,但我不同意使用save()的選項。我認爲最好的方法是使用財產虛擬領域。它似乎現在工作良好,不知道它的效率是否會持續下去:-) – user2454305

0

這不是你如何使用屬性。 property function的第一個參數,如果你這樣使用的話,那就是getter方法。你甚至沒有提供一個getter方法。你需要一個返回值self._corporate

+0

我添加getter方法作爲'高清get_corporate(個體經營): 如果self._corporate: 回報self._corporate'然後我編輯了我的財產功能到'企業=財產(get_corporate,set_corporate)'但即使這樣做它沒有工作!我是否還想念一些東西? – user2454305