基本上我有6个对象模型,3个用于常规对象,3个用于这些对象的依赖项。单独地,这些对象可以依赖于3个常规对象中的每一个的一个或多个实例。
我的问题: 这是最佳做法吗?我本质上希望能够在需要时向常规对象添加新依赖项。例如:
a = A.objects.get(id=1)
adependency = ADependencies.objects.get(dependentTo=a)
然后,我有一个包含a
的所有依赖项的对象。
或者,我确实想到了将3个依赖对象合并为一个的方法;但是,我不确定这是否是一种好习惯。
class Dependencies(models.Model):
id = models.CharField(max_length=16)
dependentTo = CharField(max_length=16)
a = models.ManyToManyField(A)
b = models.ManyToManyField(B)
c = models.ManyToManyField(C)
在这种情况下,我不使用ForeignKey映射dependentTo对象。相反,我会使用对象id来拉动对象 - 允许我成为类不可知的;但是,这需要在3个常规对象中使用唯一ID。
a = A.objects.get(id=1)
adependency = ADependencies.objects.get(dependentTo=a.id)
还有一个想法! 是否仍然可以使用ForeignKey,但是传入一个带有类名的字符串?
class Dependencies(models.Model):
id = models.CharField(max_length=16)
type = models.CharField(max_length=16)
dependentTo = ForeignKey(type)
a = models.ManyToManyField(A)
b = models.ManyToManyField(B)
c = models.ManyToManyField(C)
对象模型:
class A(models.Model):
id = models.CharField(max_length=16)
title = models.CharField(max_length=32)
summary = models.CharField(max_length=256)
class B(models.Model):
id = models.CharField(max_length=16)
title = models.CharField(max_length=32)
summary = models.CharField(max_length=256)
a = models.ForeignKey(A)
class C(models.Model):
id = models.CharField(max_length=16)
title = models.CharField(max_length=32)
summary = models.CharField(max_length=256)
b = models.ForeignKey(B)
class ADependencies(models.Model):
id = models.CharField(max_length=16)
dependentTo = models.ForeignKey(A)
a = models.ManyToManyField(A)
b = models.ManyToManyField(B)
c = models.ManyToManyField(C)
class BDependencies(models.Model):
id = models.CharField(max_length=16)
dependentTo = models.ForeignKey(B)
a = models.ManyToManyField(A)
b = models.ManyToManyField(B)
c = models.ManyToManyField(C)
class CDependencies(models.Model):
id = models.CharField(max_length=16)
dependentTo = models.ForeignKey(B)
a = models.ManyToManyField(A)
b = models.ManyToManyField(B)
c = models.ManyToManyField(C)
谢谢!
答案 0 :(得分:1)
这可以做得更简单。定义Dependency
模型而不是Dependencies
模型。您将需要contenttypes django贡献:
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
class Dependency(models.Model):
dependent_contenttype = models.ForeignKey(ContentType)
dependent_id = models.PositiveIntegerField()
dependent = GenericForeignKey('dependent_contenttype', 'dependent_id')
prerequisite_contenttype = models.ForeignKey(ContentType)
prerequisite_id = models.PositiveIntegerField()
prerequisite = GenericForeignKey('prerequisite_contenttype',
'prerequisite_id')
如果您愿意,可以在模型A
,B
和C
上使依赖关系成为反向通用关系:
class A:
# ...
dependencies = GenericRelation(
Dependency,
content_type_field='dependent_contenttype',
object_id_field='dependent_id')
答案 1 :(得分:0)
我认为继承可能会大大简化您的数据结构。
让我们按原样保留模型$var1 = 01002992456;
echo "$var1";
:
A
您的课程class A(models.Model):
id = models.CharField(max_length=16)
title = models.CharField(max_length=32)
summary = models.CharField(max_length=256)
和B
的字段为C
加上一个字段,因此我们可以将其重写为
A
现在我们有一个基类,我们只需要一个依赖类:
class B(A):
a = models.ForeignKey(A)
class C(A):
b = models.ForeignKey(B)
现在,您可以将class ADependencies(models.Model):
id = models.CharField(max_length=16)
dependentTo = models.ForeignKey(A)
dependents = models.ManyToManyField(A)
,A
和B
个对象设置为C
和dependentTo
。如果您只需要依赖项中的主对象,则dependents
类型的对象将具有属性A
,属性b
或者没有属性。您也可以查询这些属性:
c
此结构更具可伸缩性,更易于维护,因为如果需要再添加一个模型,则只需为其编写唯一代码,而不必处理依赖项类。
简化模型的另一种方法是只使用一个模型:
ADependencies.objects.filter(dependentTo__b__isnull=False)
这样您只有模型class A(models.Model):
id = models.CharField(max_length=16)
title = models.CharField(max_length=32)
summary = models.CharField(max_length=256)
a = models.ForeignKey(A, null=True)
,您可以将字段A
留空(表示它只是一个简单的a
实例)或设置A
的值(它将表示a
或B
类型的对象。然后您的依赖类与前面的示例相同,但您不需要处理那些向后关系来测试真实对象类型。
如果你真的需要在C
和B
对象之间进行区分,你可以像这样编写C
类:
A
这样,您只有一个模型类和一个依赖类,可以通过选中class A(models.Model):
A = 0
B = 1
C = 2
TYPE_CHOICES = (
(A, "A"),
(B, "B"),
(C, "C")
)
id = models.CharField(max_length=16)
title = models.CharField(max_length=32)
summary = models.CharField(max_length=256)
a = models.ForeignKey(A, null=True)
obj_type = models.IntegerField(choices=TYPE_CHOICES)
来判断对象的类型。此外,您应该实施一些检查,以防止obj_type
不是a
且null
为A且类似的情况。
如果您需要此解决方案,请告诉我。