2011-09-27 42 views
2

下面是一個精簡的模型和相關的方法。我正在尋找一種簡單的方法來執行查詢,以便在單個答案中獲得所有必需的信息,而無需重新查詢所有內容。這裏的挑戰是value取決於value_id的簽名。Django QuerySets - 帶類方法

class Property(models.Model): 
    property_definition = models.ForeignKey(PropertyDefinition) 
    owner = models.IntegerField() 
    value_id = models.IntegerField() 

    def get_value(self): 
     if self.value_id < 0: return PropertyLong.objects.get(id=-self.value_id) 
     else: return PropertyShort.objects.get(id=self.value_id) 

眼下獲得「價值」我需要這樣做:

object = Property.objects.get(property_definition__name="foo") 
print object.get_value() 

有人可以提供解決這個更清潔的方式或者是「好」就夠了嗎?理想情況下,我只想簡單地做到這一點。

object = Property.objects.get(property_definition__name="foo") 
object.value 

感謝

+0

你有沒有考慮過使用[generic relations](https://docs.djangoproject.com/en/1.3/ref/contrib/contenttypes/#generic-relations)? –

+0

嘿丹尼爾!感謝回覆 - 我沒有考慮過它。在閱讀文檔它聲明我應該使用(通常)PositiveIntegerField。我如何處理這個簽名? – rh0dium

+0

那麼我的觀點是你不需要使用正/負邏輯,因爲你可以使用'content_type'來區分你的長和短屬性。 –

回答

1

鑑於這是一個糟糕的設計。你可以使用內建的property修飾器來使你的方法成爲一個屬性。

class Property(models.Model): 
    property_definition = models.ForeignKey(PropertyDefinition) 
    owner = models.IntegerField() 
    value_id = models.IntegerField() 

    @property 
    def value(self): 
     if self.value_id < 0: return PropertyLong.objects.get(id=-self.value_id) 
     else: return PropertyShort.objects.get(id=self.value_id) 

這將使你做什麼,你會非常喜歡做的事:Property.objects.get(pk=1).value

但我會去儘可能把這種「乾淨」。 ;-)

通過擴展django.models.Field,您可以進一步編寫自己的custom model field,以隱藏架構背後的糟糕API。這至少會給你現在需要的API,所以你可以在稍後將這種缺陷遷移出去。

那或他人提到的通用密鑰。選擇你的毒藥...

1

這是一個糟糕的設計。正如Daniel Roseman所說,如果必須引用同一字段中的兩個不同模型,請查看泛型外鍵。

https://docs.djangoproject.com/en/1.3/ref/contrib/contenttypes/#generic-relations

+0

我與你在一起!這是我試圖按摩以使其工作的傳統設計。我不明白Daniels對使用'content_type'來區分這兩個屬性的評論。這就是我要找的。 – rh0dium

+0

作爲我鏈接到的文檔說,您將創建一個引用存儲內容類型的表的外鍵。他們稱這個外鍵爲「通用」。必須伴隨此外鍵的另一個輔助字段將包含具有此內容類型的對象的ID。你的多頭和空頭屬性將有不同的內容類型,因爲它們是由不同的模型建模的。這就是你將如何辨別存儲在輔助字段中的id所指向的表格。我個人只會使用兩個非通用的外鍵字段。每個屬性一個。 – akonsu