简明问题:
在不使用 through 参数的情况下在外部表上对 Django (1.5) 中的多对多关系建模有哪些优点和缺点?
详情:
比如说,我有一个自定义用户模型 UserProfile,我想定义与同一模型的 m2m 关系,例如实现跟随 关系。我可以定义一个外部表(模型)like so :
class Relationship(models.Model):
"""Relationship model"""
from_user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='from_users')
to_user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='to_users')
created = models.DateTimeField(auto_now_add=True)
is_blocked = models.BooleanField(default=False)
objects = RelationshipManager()
在这种情况下,我应该向 UserProfile 模型添加一个 m2m 字段,如下所示吗?如果是,为什么?我可以只使用 Relationship 模型处理用户之间的所有关系,不是吗?
class UserProfile(AbstractBaseUser, PermissionsMixin):
user_following = models.ManyToManyField('self', through=Relationship, symmetrical=False, related_name='followed')
最佳答案
首先,重要的是要区分数据库中的概念数据模型 (CDM) 和物理数据模型 (PDM)。
从概念上讲,如果您想将一个 UserProfile 链接到另一个 UserProfile,似乎您需要 2 个实体。
但从技术上(物理上)来说,由于您正在创建多对多关系,您的系统绝对需要创建第三个数据库来存储您的 2 个 UserProfile 之间的关系,否则它不能!
请注意,如果它是 OneToOne 或 OneToMany 关系,从技术上讲,2 个表就足够了(这解释了为什么此关键字仅存在于 ManyToMany 关系中)。
现在,了解 Django 试图让您的生活更轻松:您可能不关心“物理”层。例如,如果您只想知道哪个用户连接到其他哪些用户,而没有其他信息。
-> 在那种情况下,您不关心第三个表,它只是使您的整个工作正常进行的技术限制!不需要使用 through
关键字。
在这种情况下,您在 Django 中只看到 2 个模型,但在数据库中有 3 个表,即使您在 Django 中看不到它。
但在某些情况下(通常实际上),您可以使用这第三个表来添加有关用户之间关系的重要信息。例如,如果您想存储关系创建的日期,那么第三个表就是完美的地方。
-> 这个“技术”表变成了“功能”表:您想直接在您的项目中使用它,因为它现在包含您需要的数据以及用户之间的关系!
是时候使用 through
关键字在 Django 项目中定义第三个表,并将属性(如 assocation_date
)添加到此模型/表。
现在您在 Django 中有 3 个模型,数据库中还有 3 个表(带有您添加的附加属性)。
另一个经典例子
客户可以订购 1->N 种产品。一个产品可以被 0->N 个客户订购。这显然是多对多关系。
如果我想存储有关订单的信息(如总价、日期等),我可以在定义客户和产品之间的 M2M 关系时设置一个 through="Order"
.
然后,我在 Django 中定义了 Order 模型,然后 bingo!
关于django - 在 Django 中的 M2M 关系上使用 'through' 参数的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24152102/