Python 数据模型依赖关系,我可以简化这些对象吗?

Python 数据模型依赖关系,我可以简化这些对象吗?,python,django,Python,Django,基本上,我有6个对象模型,3个用于常规对象,3个用于这些对象的依赖关系。这些对象可以分别依赖于3个常规对象中每个对象的一个或多个实例 我的问题: 这是最佳实践吗?我基本上希望能够在需要时向常规对象添加新的依赖项。例如: a = A.objects.get(id=1) adependency = ADependencies.objects.get(dependentTo=a) 然后,我将有一个对象,其中包含a的所有依赖项 或者,我确实想到了一种将3个依赖对象合并为一个的方法;然而,我不确定这是

基本上,我有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)

谢谢

我认为继承可以大大简化数据结构

让我们将模型
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
obj_type
是a和类似的情况


如果您需要此解决方案,请告诉我。

这可以简单得多。定义
依赖关系
模型,而不是
依赖关系
模型。您将需要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')

谢谢这似乎是最好的办法。