是否(以及如何)通过django中的公共中介/连接表处理多个多对多关系?

时间:2015-05-07 15:44:56

标签: python django

我有几个模型实现了所谓的“可标记”'行为:

class Tag(models.Model):
    name = models.CharField(max_length=200)


class Taggable(models.Model):
    tags = models.ManyToManyField(Tag)

    class Meta:
        abstract = True


class A(Taggable):
...

class B(Taggable):
...

class C(Taggable): 
...

class D(Taggable):
...

此方案导致为从Taggable继承的每个模型创建中间表。即,

appname_a_tags
appname_b_tags
appname_c_tags
appname_d_tags

我仍处于开发的开始阶段,此类模型和表格的数量可能会增加。因此,让我感到困扰的是,有一些具有相似数据的表格混乱,而且,将来,我可能需要应用程序中分配的所有标签的通用功能(例如,收集在哪里使用哪些标签的统计数据,或者可能用于搜索功能)。

现在,我的问题是:从一般工程的角度来看,对于使用这个' Taggable'的所有模型,使用一个公共中介/连接表是可行的。行为?如果是这样,这样做的缺点是什么,并且是解决这个问题的最佳方法。

在django中成为新手,如果我不得不这样做,我会尝试(或研究更多)这两个场景:

情景1:

  • 包括一个'班级'上面标记模型中的字段将保留标记所分配的ojbect类型(例如,A,B,C或D)
  • 为A,B,C,D(例如,ATag,BTag,..)中的每一个创建代理Tag类,覆盖models.Model类' '保存'方法是为了更新课程'专栏。我还必须自定义模型管理器,以便过滤并正确检索仅属于该类的标签。
  • 让每个类使用其自定义Tag类。即,

    class A(models.Model):
        tags = models.ManyToManyField(ATags)
        ...
    

情景2:

  • 创建一个共同的中间模型TagAssigned,并包含额外的'类'除了标签和标记的项目的2个外键之外的字段
  • 使用TagAssigned作为所有4个类的中间表。例如,

    Class A(models.Model)
        tags = models.ManyToManyField(Tag, through='TagAssigned')
        ...
    
  • 覆盖并自定义'保存'方法和类A,B,C和D的模型管理器(与方案1中的代理模型相对)

1 个答案:

答案 0 :(得分:1)

我建议尽可能简单地保持你的初始实现(例如没有代理表没有覆盖保存)并且不要担心表的数量,除非你达到一些非常惊人的数字,用它或其他方面遇到某些严重问题超出“简单标签”的用处。这可能会为您节省一个您可能首先不需要的毛茸茸的实现。

P.S。我正在使用https://github.com/alex/django-taggit,它非常方便且易于使用。刚刚看到repo在gitgub中有大约60个问题:)但我还没有碰到任何一个。