[英]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 的東西:從子類到超類( Restaurant
到Place
)進行一對一引用
我在這里看到一個問題:
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.