【问题标题】:Django related model field querying (mutual friends)django相关模型字段查询(共同好友)
【发布时间】:2019-11-07 17:23:10
【问题描述】:

我有一个友谊模型:


class Friendship(models.Model):
    user = models.ForeignKey(
        Account, on_delete=models.CASCADE, related_name="friend1", null=True, blank=True)
    other_user = models.ForeignKey(
        Account, on_delete=models.CASCADE, related_name="friend2", null=True, blank=True)
    date_created = models.DateTimeField(auto_now=True)

    objects = FriendshipManager()

    class Meta:
        verbose_name = "friendship"
        verbose_name_plural = "friendships"
        unique_together = ("user", "other_user")

    def __str__(self):
        return f'{self.user} is friends with {self.other_user}.'

此函数返回两个帐户的共同好友的所有用户


def mutual_friends(self, account1, account2):
        mutual_friends = Account.objects.filter(
            Q(friend2__user=account1) & Q(friend2__user=account2))
        return mutual_friends

根据我对查询 api 工作原理的(有限)理解,我认为这应该返回与 Friendship 表有“friend2”关系的所有用户,其中“friend1”用户是 account1 或 account2。我仍然习惯于使用 django 进行查询,所以如果有人可以让我知道我做错了什么,那就太好了。

谢谢!

【问题讨论】:

    标签: python sql django django-rest-framework


    【解决方案1】:

    您的模型设计对我来说似乎不合适。到目前为止,您可以将任何Account 实例设置为userother_user,并且由于它们都引用相同的模型(Account),在从数据库中进行任何检索时,您需要考虑两者字段。

    更好的设计 IMO 是在 Account 模型中对自己使用 ManyToManyField(多对多关系),因为一个帐户可以有多个其他帐户作为朋友,反之亦然。所以:

    class Account(models.Model):
        ...
        friends = models.ManyToManyField('self')
        ...
    

    现在,您可以添加朋友,例如:

    account_foo.friends.add(account_bar, account_spam)
    

    account_*Account 实例。

    你可以得到account_foo的所有朋友点赞:

    account_foo.friends.all()
    

    查看many-to-many doc,了解各种数据集成和查询示例。


    现在,要找到例如的共同朋友。 account_fooaccount_bar,可以先获取account_foo的所有好友,然后看看有哪些也是account_bar的好友:

    friends_with_foo = account_foo.friends.values_list('pk', flat=True)
    mutual_friends_of_foo_bar = account_bar.friends.filter(pk__in=friends_with_foo)
    

    【讨论】:

    • 它是一个双向系统,当用户添加好友时,它会创建两个好友,a 是 b 的好友,b 是 a 的好友
    • @pererasys 这正是上面的ManyToManyField 所做的。
    • 我也有更多关于我想要存储的友谊的信息,根据你的建议我可以使用直通模型,但是与我当前的实现相比有什么优势
    • @pererasys 就像我说的,当您在模型中添加一个帐户时,您总是将其添加为userother_user 还是两者都添加? ForeignKey 是多对一的,我想你没有考虑过。
    • 当用户 A 将用户 B 添加为好友时,会创建两个好友。第一个:用户=A,其他用户=B;第二:user=B, other_user=A,这就是为什么我可以通过查询 Q(friend2__user=account) 来获取所有朋友帐户的
    猜你喜欢
    • 1970-01-01
    • 2021-11-14
    • 2015-08-31
    • 2020-07-31
    • 1970-01-01
    • 2012-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多