Basically, I have a model where I've created a superclass that many other classes share, and then each of those classes has some unique features that differ from each other. Let's say class A is the superclass, and class B, C, and D are children of that class.
基本上,我有一个模型,在这个模型中我创建了一个超类,许多其他类都共享这个超类,然后每个类都有一些彼此不同的独特特性。A类是超类,B类,C类和D类是该类的子类。
Both class B and class C can have multiples of class D, however I've seen that it's best to put the foreign key relationship in class D, which then refers to its parent class. Now in other languages, I could simply say it has a ForeignKey relationship to class A, and then the language recognizes the classes' true type. However, I don't think that's how it works with Python.
B类和C类都可以有D类的倍数,但是我发现最好将外键关系放在D类中,然后它就会引用它的父类。在其他语言中,我可以简单地说它与a类有一个foreign - key关系,然后语言就能识别类的真正类型。然而,我不认为这是它与Python的合作方式。
What's the best recommended way of pursuing this issue?
对于这个问题,最好的建议是什么?
EDIT: Here is roughly what I mean...
编辑:这里大致是我的意思……
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.
Essentially, class B and class C both have multiple class D's. But a particular class D only belongs to one of them.
实质上,B类和C类都有多个D类。但是一个特定的D类只属于其中的一个。
4 个解决方案
#1
3
From the Django Docs:
Django的文档:
For example, if you were building a database of "places", you would build pretty standard stuff such as address, phone number, etc. in the database. Then, if you wanted to build a database of restaurants on top of the places, instead of repeating yourself and replicating those fields in the Restaurant model, you could make Restaurant have a OneToOneField to Place (because a restaurant "is a" place; in fact, to handle this you'd typically use inheritance, which involves an implicit one-to-one relation).
例如,如果您正在构建一个“places”的数据库,那么您将在数据库中构建非常标准的内容,比如地址、电话号码等。然后,如果你想在这些地方建立一个餐馆的数据库,而不是重复你自己在餐馆模型中复制这些字段,你可以让餐馆有一个单独的地方(因为餐馆是一个地方;实际上,要处理这个问题,通常需要使用继承,它涉及到隐式的一对一关系)。
Normally, you would just have Restaurant
inherit from Place
. Sadly, you need what I consider a hack: making a one-to-one reference from subclass to superclass (Restaurant
to Place
)
通常情况下,你只会让餐馆从当地继承。遗憾的是,您需要我考虑的一个技巧:从子类到超类(从餐厅到位置)进行一对一引用
#2
2
I see a problem here:
我发现这里有一个问题:
class D(A):
#D has foreign key to either B or C, but not both.
Can't do it. You'll have to add both because in SQL columns must be defined exactly.
不能这么做。您必须同时添加这两项,因为在SQL列中必须准确地定义。
Also even though inherited models like you have compile with syncdb
- they don't seem to behave like you would expect - at least I could not make them work. I can't explain why.
此外,即使继承的模型(如您使用syncdb编译的模型)——它们的行为似乎不像您期望的那样——至少我不能让它们工作。我不能解释为什么。
This is how FK works in Django
这就是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')
this way you can effectively have multiples of D in B.
这样你可以有效地得到D在B中的倍数。
Inheritance in models (e.g. class B(A)) doesn't work as I would expect it. Maybe someone else can explain it better.
模型中的继承(如B类(A))并不像我预期的那样有效。也许有人能更好地解释一下。
Take a look at this doc page. It's about many-to-one relationship in django.
看看这个文档页面。这是关于django中多对一的关系。
b = B()
b.D_set.create(...)
#3
2
You could also do a generic relation http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#id1 and check the types to constrain it to B or C when setting or saving. This is probably more work than figuring out the direct reference, but might feel cleaner.
您还可以执行一个泛型关系http://docs.djangoproject.com/en/dev/ref/后悔/contenttypes/#id1,并在设置或保存时检查将其约束到B或C的类型。这可能比计算直接引用要复杂,但可能会让人感觉更清晰。
#4
2
One way to do this is to add an intermediate class as follows:
一种方法是增加一个中间类,如下所示:
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
Using an intermediate class (Target) guarantees that there will only be one link from D to either B or C. Does that make sense? See http://docs.djangoproject.com/en/1.2/topics/db/models/#model-inheritance for more information.
使用一个中间类(目标)保证从D到B或c只有一个链接,这有意义吗?有关更多信息,请参见http://docs.djangoproject.com/en/1.2 topics/db/models/#模型继承。
In your database there will be tables for Target, B, C and D, but not A, because that was marked as abstract (instead, columns related to attributes on A will be present in Target and D).
在您的数据库中,将有目标、B、C和D的表,但没有A,因为这被标记为抽象(相反,与A上的属性相关的列将出现在目标和D中)。
[Warning: I have not actually tried this code - any corrections welcome!]
[警告:我还没有尝试过这个代码-欢迎任何修改!]
#1
3
From the Django Docs:
Django的文档:
For example, if you were building a database of "places", you would build pretty standard stuff such as address, phone number, etc. in the database. Then, if you wanted to build a database of restaurants on top of the places, instead of repeating yourself and replicating those fields in the Restaurant model, you could make Restaurant have a OneToOneField to Place (because a restaurant "is a" place; in fact, to handle this you'd typically use inheritance, which involves an implicit one-to-one relation).
例如,如果您正在构建一个“places”的数据库,那么您将在数据库中构建非常标准的内容,比如地址、电话号码等。然后,如果你想在这些地方建立一个餐馆的数据库,而不是重复你自己在餐馆模型中复制这些字段,你可以让餐馆有一个单独的地方(因为餐馆是一个地方;实际上,要处理这个问题,通常需要使用继承,它涉及到隐式的一对一关系)。
Normally, you would just have Restaurant
inherit from Place
. Sadly, you need what I consider a hack: making a one-to-one reference from subclass to superclass (Restaurant
to Place
)
通常情况下,你只会让餐馆从当地继承。遗憾的是,您需要我考虑的一个技巧:从子类到超类(从餐厅到位置)进行一对一引用
#2
2
I see a problem here:
我发现这里有一个问题:
class D(A):
#D has foreign key to either B or C, but not both.
Can't do it. You'll have to add both because in SQL columns must be defined exactly.
不能这么做。您必须同时添加这两项,因为在SQL列中必须准确地定义。
Also even though inherited models like you have compile with syncdb
- they don't seem to behave like you would expect - at least I could not make them work. I can't explain why.
此外,即使继承的模型(如您使用syncdb编译的模型)——它们的行为似乎不像您期望的那样——至少我不能让它们工作。我不能解释为什么。
This is how FK works in Django
这就是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')
this way you can effectively have multiples of D in B.
这样你可以有效地得到D在B中的倍数。
Inheritance in models (e.g. class B(A)) doesn't work as I would expect it. Maybe someone else can explain it better.
模型中的继承(如B类(A))并不像我预期的那样有效。也许有人能更好地解释一下。
Take a look at this doc page. It's about many-to-one relationship in django.
看看这个文档页面。这是关于django中多对一的关系。
b = B()
b.D_set.create(...)
#3
2
You could also do a generic relation http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#id1 and check the types to constrain it to B or C when setting or saving. This is probably more work than figuring out the direct reference, but might feel cleaner.
您还可以执行一个泛型关系http://docs.djangoproject.com/en/dev/ref/后悔/contenttypes/#id1,并在设置或保存时检查将其约束到B或C的类型。这可能比计算直接引用要复杂,但可能会让人感觉更清晰。
#4
2
One way to do this is to add an intermediate class as follows:
一种方法是增加一个中间类,如下所示:
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
Using an intermediate class (Target) guarantees that there will only be one link from D to either B or C. Does that make sense? See http://docs.djangoproject.com/en/1.2/topics/db/models/#model-inheritance for more information.
使用一个中间类(目标)保证从D到B或c只有一个链接,这有意义吗?有关更多信息,请参见http://docs.djangoproject.com/en/1.2 topics/db/models/#模型继承。
In your database there will be tables for Target, B, C and D, but not A, because that was marked as abstract (instead, columns related to attributes on A will be present in Target and D).
在您的数据库中,将有目标、B、C和D的表,但没有A,因为这被标记为抽象(相反,与A上的属性相关的列将出现在目标和D中)。
[Warning: I have not actually tried this code - any corrections welcome!]
[警告:我还没有尝试过这个代码-欢迎任何修改!]