【问题标题】:Having trouble wrapping my head around follower/target models in Models.py无法在 Models.py 中围绕追随者/目标模型进行思考
【发布时间】:2020-09-27 06:44:27
【问题描述】:

我刚刚开始创建一个与 Pinterest 类似的网站,并且该网站具有我几乎不了解的追随者/目标系统。到目前为止,我的 models.py 代码如下:

from django.db import models

class User(models.Model):
    username    = models.CharField(max_length=45, null=True)
    email       = models.CharField(max_length=200, null=True)
    password    = models.CharField(max_length=200)
    nickname    = models.CharField(max_length=45, null=True)
    target      = models.ManyToManyField(self, through='Follow')
    follower    = models.ManyToManyField(self, through='Follow')

    class Meta:
        db_table = 'users'

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

    class Meta:
        db_table = 'follows'

这段代码参考了另一个 StackOverflow 线程 Django models: database design for user and follower 但是,我无法理解如何在 'follower' 中使用 "related_name='targets' 和在 'target' 中使用 "related_name='followers'" 我看不到任何 'targets'(复数)或 'followers'(复数) 在models.py的其他领域

我应该去掉那个related_name,因为没有这样的表叫做“followers”或“targets”吗?如果你在我的代码或逻辑中发现重大错误,你能告诉我吗?谢谢!

【问题讨论】:

  • related_name 表示django添加了与其他模型的关系,因此您可以通过myuser.followers获取target引用的相关Follow对象。

标签: python django django-models


【解决方案1】:

我应该摆脱那个related_name,因为没有这样的表称为followerstargets

从来没有一个名为followerstargets 的表。 related_name [Django-doc] 是 Django 与其他模型(在本例中为 User)建立的概念关系。这意味着对于User 对象myuser,您可以访问通过target 引用该用户的Follow 对象,例如myuser.followers.all(),所以:

Follow.objects.filter(target=myuser)

相当于:

myuser<b>.followers</b>.all()

related_name 的默认值是<i>modelname</i>_set,所以这里是follow_set。但是,如果您同时删除了两个related_names,那么这将导致名称冲突,因为不能将两个关系follow_set 添加到User 模型(并且每个关系具有不同的语义值)。

如果你发现我的代码或逻辑中有重大错误,你能告诉我吗?

问题在于,由于ManyToManyFields 引用'self'(它应该是'self' 作为字符串文字),所以“源”和目标是什么是模棱两可的,此外 Django 会假设关系是symmetrical [Django-doc],但事实并非如此。您应该指定源和目标外键是什么,您可以使用through_fields=… parameter [Django-doc] 来做到这一点。此外,最好将ManyToManyFieldrelated_name简单地反向定义,以避免重复逻辑。

from django.db import models

class User(models.Model):
    username = models.CharField(max_length=45, unique=True)
    email = models.CharField(max_length=200)
    password = models.CharField(max_length=200)
    nickname = models.CharField(max_length=45)
    follows = models.ManyToManyField(
        'self',
        through='Follow',
        symmetrical=False,
        related_name='followed_by',
        through_fields=('follower', 'target')
    )

    class Meta:
        db_table = 'users'

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

    class Meta:
        db_table = 'follows'

这里User 对象myuser 可以访问myuser.follows.all() 以访问他们关注的所有用户,myuser.followed_by.all() 是关注Users 的集合myusermyuser.targets.all() 是他关注的Follow 对象的集合,myuser.followers.all() 是关注该用户的Follow 对象的集合。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-13
    • 2017-05-13
    • 1970-01-01
    • 2021-11-25
    • 2021-10-09
    • 2012-09-03
    • 2020-05-14
    • 2021-02-18
    相关资源
    最近更新 更多