簡體   English   中英

Django 模型繼承和外鍵

[英]Django Model Inheritance And Foreign Keys

基本上,我有一個模型,我在其中創建了許多其他類共享的超類,然后這些類中的每一個都具有一些彼此不同的獨特功能。 假設 A 類是超類,B、C 和 D 類是該類的子類。

B 類和 C 類都可以有 D 類的倍數,但是我看到最好將外鍵關系放在 D 類中,然后 D 類引用其父類。 現在在其他語言中,我可以簡單地說它與類 A 具有 ForeignKey 關系,然后該語言可以識別類的真實類型。 但是,我認為這不是它與 Python 一起工作的方式。

解決此問題的最佳推薦方法是什么?

編輯:這大致是我的意思......

class A(models.Model):
    field = models.TextField()

class B(A):
    other = <class specific functionality>

class C(A):
    other2 = <different functionality>

class D(A):
    #I would like class D to have a foreign key to either B or C, but not both.

本質上,B 類和 C 類都有多個 D 類。 但是一個特定的 D 類只屬於其中一個。

一種方法是添加一個中間類,如下所示:

class A(Model):
    class Meta(Model.Meta):
        abstract = True
    # common definitions here

class Target(A):
    # this is the target for links from D - you then need to access the 
    # subclass through ".b" or ".c"
    # (no fields here)

class B(Target):
    # additional fields here

class C(Target):
    # additional fields here        

class D(A):
    b_or_c = ForeignKey(Target)
    def resolve_target(self):
        # this does the work for you in testing for whether it is linked 
        # to a b or c instance
        try:
            return self.b_or_c.b
        except B.DoesNotExist:
            return self.b_or_c.c

使用一個中間類(Target)保證從 D 到 B 或 C 只有一個鏈接。這有意義嗎? 有關詳細信息,請參閱模型繼承

在您的數據庫中會有 Target、B、C 和 D 的表,但 A 不會,因為它被標記為抽象(相反,與 A 上的屬性相關的列將出現在 Target 和 D 中)。

[警告:我還沒有真正嘗試過這段代碼——歡迎任何更正!]

您還可以做一個通用關系http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#id1並檢查類型以在設置或保存時將其約束為 B 或 C。 這可能比找出直接引用需要更多的工作,但可能感覺更清晰。

來自Django 文檔

例如,如果您要構建“地點”數據庫,您會在數據庫中構建非常標准的內容,例如地址、電話號碼等。 然后,如果你想在這些地方之上建立一個餐廳數據庫,而不是重復你自己並在 Restaurant 模型中復制這些字段,你可以讓 Restaurant 有一個 OneToOneField 來放置(因為餐廳“是一個”地方;在事實上,要處理這個問題,您通常會使用繼承,這涉及隱式的一對一關系)。

通常,您只會讓Restaurant繼承自Place 可悲的是,你需要我認為是 hack 的東西:從子類到超類( RestaurantPlace )進行一對一引用

我在這里看到一個問題:

class D(A):
    #D has foreign key to either B or C, but not both.

做不到。 您必須同時添加兩者,因為在 SQL 中必須准確定義列。

此外,即使像您這樣的繼承模型已使用syncdb進行編譯 - 它們的行為似乎並不像您期望的那樣 - 至少我無法讓它們工作。 我無法解釋為什么。

這就是 FK 在 Django 中的工作方式

class A(models.Model):
    a = models.CharField(max_length=5)

class B(models.Model):
    a = model.ForeignKey(A, related_name='A')
    b = models.CharField(max_length=5)

class D(models.Model):
    a = model.ForeignKey(A, related_name='A')
    parent = model.ForeignKey(B, related_name='D')

這樣你就可以有效地在 B 中擁有 D 的倍數。

模型中的繼承(例如 B(A) 類)並不像我期望的那樣工作。 也許其他人可以更好地解釋它。

看看 這個文檔頁面。 這是關於 django 中的多對一關系。

b = B()
b.D_set.create(...)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM