【问题标题】:Modeling Complex Relationships in Django在 Django 中建模复杂的关系
【发布时间】:2013-02-03 11:56:59
【问题描述】:

好的,这是一个挑战,Djangonistas!

假设我的项目有 3 种数据。

  • 项目
  • 音频
  • 视频

项目可以引用无限数量的视频和音频对象,以及对其他项目的无限引用。

对此建模的最佳方法是什么?它必须以通用方式完成,以便将来可以添加新的对象类型(图像、链接、气味等),并且对象可以被多个项目引用。

我有 3 个关于如何做到这一点的理论。

#1:继承

创建一个 BaseModel 类并让所有其他对象继承自它。

class BaseModel(models.Model)
class Project(BaseModel)
class Video(BaseModel)
etc

然后,在 Project 类中为所有 BaseModel 设置一个 ManyToMany 字段。

class Project(BaseModel):
    content = models.ManyToManyField(BaseModel)

这会有效吗?

#2:通用外键

我还可以设置使用 GenericForeignKey 字段的系统,该字段可以使用 ContentTypes 框架

content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')

(我认为这可能是最糟糕的想法。)

#3:通用多对多键

最后,我可以有一个单独的表来维护对象之间的所有关系。

class RelatedObject(models.Model):
    """
    A generic many-to-many implementation where diverse objects are related
    across a single model to other diverse objects -> using a dual GFK
    """
    # SOURCE OBJECT:
    parent_type = models.ForeignKey(ContentType, related_name="child_%(class)s")
    parent_id = models.IntegerField(db_index=True)
    parent = GenericForeignKey(ct_field="parent_type", fk_field="parent_id")

    # ACTUAL RELATED OBJECT:
    object_type = models.ForeignKey(ContentType, related_name="related_%(class)s")
    object_id = models.IntegerField(db_index=True)
    object = GenericForeignKey(ct_field="object_type", fk_field="object_id")

    alias = models.CharField(max_length=255, blank=True)
    creation_date = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ('-creation_date',)

    def __unicode__(self):
        return '%s related to %s ("%s")' % (self.parent, self.object, self.alias)

然后

class Project(models.Model):
    related = RelatedObjectsDescriptor()

Charles Leifer 在这里更详细地阐述了这一点:http://charlesleifer.com/blog/connecting-anything-to-anything-with-django/ 和他的 django-generic-m2m 项目:https://github.com/coleifer/django-generic-m2m

怎么办?

那么,这些存储关系的方法各自的优缺点是什么?哪个最快,哪个更容易编写和维护?您过去使用过哪些方法?

非常感谢!

【问题讨论】:

  • 项目和其他项目之间需要一对多还是多对多?

标签: django orm many-to-many data-modeling django-orm


【解决方案1】:

我会说您将要使用'self' 作为Project 模型的ManyToManyField 的参数(而不是示例中的继承)。这允许您定义自引用模型。

如果您查看https://docs.djangoproject.com/en/dev/ref/models/fields/#foreignkey - 您会看到下面的两行,有以下注释:

要创建递归关系(与自身具有多对一关系的对象),请使用 models.ForeignKey('self')。

...我从 2008 年的这篇博文中第一次了解到这一点(现在在某些方面可能已经过时,但在使用这种技术时我仍然会参考它):

http://eflorenzano.com/blog/2008/05/17/exploring-mixins-django-model-inheritance/

真的,祝你好运先生。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多