2012-06-30 63 views
2

我的願望是有一個共同的選址模型,然後讓誰需要一個位置是指它的各種更高級別的車型。Django管理在線和架構設計

我想提出我的用戶管理與多部分的形式(內嵌),允許他們進入了發佈,建設更高水平的信息,以及每個位置信息。內聯繫統似乎不希望以這種方式工作。

很顯然,我做的事情非常錯誤的,因爲這似乎是一個非常標準的問題也給我。我的模式設計是否受到束縛?

我在愚蠢地使用內聯繫統嗎?我不想爲每個上級對象做位置的子類,因爲我想操縱獨立(郵件列表,或地理的查找也許)

models.py: 
... 
class Location(models.Model): 
    """ 
    A geographical address 
    """ 
# Standard Location stuff 
    address_line1 = models.CharField("Address line 1", max_length = 45, null=True, blank=True) 
    ... 

class Publisher(models.Model): 
    """ 
    Contains Publisher information for publishers of yearbooks. Replaces Institution from 1.x 
    """ 
    name = models.CharField(max_length=100, null=False, help_text="Name of publisher, e.g. University of Kansas") 
    groups = models.ManyToManyField(Group, help_text="Select groups that this publisher owns. Usually just one, but multiple groups are possible.") 
    is_active = models.BooleanField(help_text="Check this box to enable this publisher.") 
    location = models.OneToOneField(Location) 
    ... 

class Building(models.Model): 
    """ 
    Contains Building Information 
    """ 
    name = models.CharField(max_length=100, null=False, help_text="Name of building, e.g. Physical Sciences") 
    is_active = models.BooleanField(help_text="Check this box to enable this building.") 
    location = models.OneToOneField(Location) 
    ... 

admin.py: 
... 
class LocationInline(generic.GenericStackedInline): 
    model = Location 
    max_num = 1 
    extra = 1 

class PublisherAdmin(admin.ModelAdmin): 
    model = Publisher 
    inlines = [ LocationInline, 
    ] 

class BuildingAdmin(admin.ModelAdmin): 
    model = Building 
    inlines = [ LocationInline, 
    ] 

admin.site.register(Publisher, PublisherAdmin) 
admin.site.register(Building, BuildingAdmin) 
的任何高層對象擁有這些不同方式的位置

我可以強制在線加載並通過加入這個到選址模型:

# Support reverse lookup for admin 
    object_id = models.PositiveIntegerField() 
    content_type = models.ForeignKey(ContentType) 
    of   = generic.GenericForeignKey('content_type', 'object_id') 

但我這樣做,即使我得到一個內聯對象,並可以對其進行編輯時,這種關係似乎倒退對我來說,位置存儲一個id到創建它的對象。

任何幫助是值得歡迎的,無論是所推薦模式的改變,使一切工作奇妙(如Django的是那麼好)或技巧,使向後似乎的東西是有意義的。

回答

1

首先,我想你想ForeignKey的,不OneToOneField。否則,您可能只需將您的位置字段添加到發佈者和構建模型。然後,只需在建築物和發佈商管理員的幫助下,選擇一個下拉菜單以選擇位置並添加一個新鏈接即可。

如果你真的想每建築/出版商一個位置情況下,你將不能夠因爲聯模型需要有一個ForeignKey指向父模型,除非你加入通用編輯它作爲內嵌外鍵。這不是'倒退' - 當你希望一個對象能夠將自己附加到任何其他類型時,這是一個有效的選項,無論類型如何。

+0

這就是我想念格雷格。將_itself_附加到另一個對象的概念,而「父」對象沒有任何意識。我的OneToOne字段在這種情況下是多餘的。得到它了。謝謝。 –

1

當涉及到領域模型,有沒有這樣的事,作爲一個「一個正確的方式」來做到這一點,這取決於您的特定應用的需求。

WRT /你的問題:

的OneToOne場限制了你的模型,每個模型實例,它(格雷戈mentionned)一個位置不概念從只需直接在模型中堅持位置的領域非常不同。 wrt/DRY /因式分解/重用等,你可以使用模型繼承來完成這項工作,它有一個抽象的(或者最終具體的,如果它對你的應用有意義)位置模型。

ForeignKey解決方案仍然將發佈商和構建模型限制爲單個位置(可能 - 不是 - 您想要的),但給定的位置可能會在不同的發佈者和/或構建實例之間共享。這意味着編輯一個給定的位置將反映所有相關的實例(這裏提防不需要的副作用)。

在位置模型中使用GenericForeignKey意味着給定位置實例屬於一個並且只有一個相關對象。沒有像上述解決方案那樣的浪費副作用,但是您可能有相同值的重複位置(即一個用於建築物,一個用於發佈商),並且您將無法查找特定位置的所有相關對象(或至少不那麼容易)。此外,這不會阻止發佈商或構建實例擁有多個位置,這可能再好不過。 wrt /位置實例「存儲他們所屬的對象的id」,好吧,這就是這個設計選擇的真正含義:一個Location「屬於」某個其他對象,句點。

在任何情況下,圍繞Django的管理應用程序的默認行爲進行設計可能不是最明智的做法。您必須先決定這個應用程序有什麼意義(您可能對發佈商和建築物有不同的需求),然後可能會擴展管理以滿足您的需求。

+0

謝謝你的回答。我知道FK和OneToOne的一般限制。格雷格在下面的答案中將我排除在外。對我來說,這是一個概念性的掛斷,認爲我必須從我的父母向孩子進行前向引用,實際上,我真正想要的是一個可以將_itself_附加到任意父母的孩子。 –