【问题标题】:Reasons to use 'through' parameter on an M2M relationship in Django在 Django 中对 M2M 关系使用“通过”参数的原因
【发布时间】:2014-07-31 20:55:28
【问题描述】:

简明问题:
在不使用 through 参数的情况下,在 Django (1.5) 中在外部表上建模多对多关系有哪些优点和缺点?

详情:
比如说,我有一个自定义用户模型 UserProfile,我想定义一个与同一模型的 m2m 关系,例如实现一个 following 关系。我可以定义一个外部表(模型)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')

【问题讨论】:

    标签: django django-users django-orm django-custom-user


    【解决方案1】:

    【讨论】:

      【解决方案2】:

      首先,重要的是要区分数据库中的概念数据模型 (CDM) 和物理数据模型 (PDM)。

      从概念上讲,如果您想将一个 UserProfile 链接到另一个 UserProfile,您似乎需要 2 个实体。

      但从技术上(物理上),由于您正在创建多对多关系,您的系统绝对需要创建第三个数据库来存储您的 2 个用户配置文件之间的关系,否则它不能!

      请注意,如果它是 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 模型,然后宾果游戏!

      【讨论】:

      • 是的,好的,我知道这一点,问题是:如果我使用已经定义 M2M(关系)的外部表而不将它与 m2m 字段和“通过”参数链接怎么办?优点/缺点?
      • 我想你不应该那样做。如果你为自己定义了一个为关系制作的表,你应该告诉 Django 使用它。如果你不这样做,Django 应该如何知道他必须使用它来建立关系?要回答您的问题,我认为没有优势(也许有,但请告诉我^^),只有劣势:为 M2M 制作的所有 Django 机制都不会自动工作。
      猜你喜欢
      • 2016-05-07
      • 1970-01-01
      • 1970-01-01
      • 2012-02-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-05
      • 1970-01-01
      相关资源
      最近更新 更多