首页 文章

在Django中对M2M关系使用'through'参数的原因

提问于
浏览
1

Concise question:
在不使用through参数的情况下,在外部表上对Django(1.5)中的多对多关系建模有什么优缺点?

Details:
说,我有一个自定义用户模型 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')

2 回答

  • 1
  • 0

    首先,在数据库中区分概念数据模型(CDM)和物理数据模型(PDM)非常重要 .

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

    但从技术上(物理上),由于你创建了一个多对多关系,你的系统绝对需要创建第三个数据库来存储你的2个UserProfiles之间的关系,否则它不能!

    请注意,如果它是OneToOne或OneToMany关系,从技术上讲,2个表就足够了(这解释了为什么此关键字仅存在于ManyToMany关系中) .

    现在,了解Django试图让你的生活更轻松:你可能不关心“物理”层 . 例如,如果您只想知道哪个用户连接到哪个其他用户,而没有其他信息 .

    • 在这种情况下,你不关心第三个表只是一个技术限制,使你的整个东西工作!不需要使用 through 关键字 . 在这种情况下,你只能在Django中看到2个模型,但是在数据库中有3个表,即使你没有在Django中看到它 .

    但在某些情况下(通常实际上),您可以使用此第三个表来添加有关用户之间关系的重要信息 . 例如,如果要在创建关系时存储日期,则第三个表是最佳位置 .

    • 这个"technical"表变成了"functional"表:你想直接在你的项目中使用它,因为它现在包含你需要的数据以及用户之间的关系!现在是时候使用 through 关键字在Django项目中定义第三个表,并将属性(如 assocation_date )添加到此模型/表中 . 现在你在Django中有3个模型,你的数据库中还有3个表(你添加了额外的属性) .

    Another classical example

    客户可以订购1-> N个产品 . 可以通过0-> N个客户订购产品 . 这显然是ManyToMany Relashionship .

    如果我想存储有关订单的信息(如总价格,日期等),我可以在定义客户和产品之间的M2M关系时设置 through="Order" . 然后,我在Django和宾果游戏中定义Order模型!

相关问题