【问题标题】:Django models: database design for user and followerDjango 模型:用户和关注者的数据库设计
【发布时间】:2017-02-25 10:08:07
【问题描述】:

在 Django 模型中,我正在制作一个“追随者”表,其中包含:

user's id. (this is followed by)
user's id (this is follower)

用户可以关注其他用户,这很简单。

我应该如何在 Django 中定义模型?

我试过了,但不起作用:

user = models.ForeignKey('self')
follower_id = models.ForeignKey('self')

这应该怎么做?

谢谢

【问题讨论】:

    标签: django postgresql model psql


    【解决方案1】:

    除非您有一个名为 self 的模型,否则“self”参数将不起作用。

    假设您的分配模型称为Following,并且您使用的是内置的User 模型,那么您可以这样做:

    class Following(models.Model):
        target = models.ForeignKey('User', related_name='followers')
        follower = models.ForeignKey('User', related_name='targets')
    

    这可能需要一些进一步的唯一性和验证逻辑。

    注意related_name 属性,参见https://docs.djangoproject.com/en/1.10/ref/models/fields/#django.db.models.ForeignKey.related_name。这意味着对于给定的用户对象,您可以使用user.targets.all() 获取他们关注的用户,并使用user.followers.all() 获取关注他们的用户。

    另请注意,Django 在 ORM 中返回目标模型实例,而不是 ID。这意味着即使底层表可能被称为follower_id,在 python 代码中following.follower 将返回一个实际的用户对象。

    【讨论】:

    • 我这样做了..但我得到了这个错误:main.followers.follower_id: (fields.E304) 'followers.follower_id' 的反向访问器与 'followers.user' 的反向访问器冲突。提示:在“followers.follower_id”或“followers.user”的定义中添加或更改相关名称参数。
    • 啊,是的。 Django 创建反向关系,以便您可以反向跟踪关系。我已修改我的答案以添加 related_name 属性。
    • 我还从您上面的回溯中注意到您的表称为Followers。这是一件小事,但惯例是使用单数名词作为类名。我选择了Following,因为此类的一个对象代表另一个用户的一个用户关注。不过,给事物命名很难,而且这也不是最容易封装的。
    • 在实例化类中,self(名称,而不是 'self' 字符串)返回当前实例。要参考模型,您可以使用self.__class__。您还可以查看 contenttypes 框架以了解实现此目的的其他方式。但是,在这里您要引用 User 模型,而不是递归地引用此 Follow/Followers 模型。
    【解决方案2】:

    看成Following 实际上是through 表,用于用户之间的多对多关系。我将创建一个扩展 Django User 模型的 Profile 模型,然后声明多对多关系(使用 ManyToManyField)。

    from django.contrib.auth.models import User
    from django.db import models
    
    class Profile(models.Model):
        user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
        following = models.ManyToManyField(User, related_name='followers')
    

    【讨论】:

      【解决方案3】:

      使用多对多字段。

      followers = models.ManyToManyField('self', symmetrical=False)

      【讨论】:

        猜你喜欢
        • 2021-07-21
        • 1970-01-01
        • 2011-10-02
        • 2017-10-06
        • 2012-12-10
        • 2011-03-07
        • 2019-03-24
        • 2018-12-11
        • 1970-01-01
        相关资源
        最近更新 更多