You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中如何根据related_name控制UserFollowing模型的__str__输出?

问题描述

我定义了如下的UserFollowing模型:

class UserFollowing(models.Model):
    user = models.ForeignKey(CustomUser, related_name="following", on_delete=models.CASCADE)
    following_user = models.ForeignKey(CustomUser, related_name="followers", on_delete=models.CASCADE)
    created = models.DateTimeField(default=timezone.now, db_index=True)
    
    def __str__(self):
        return f"{self.user} follows {self.following_user}"

当我调用以下代码时:

>>> user = CustomUser.objects.get(id=1) # 某一用户
>>> user.following.all() # 显示“A follows B”
>>> user.followers.all() # 显示“B follows A”

但我希望实现的效果是:

>>> user.following.all() # 显示B(因为A关注了B)
>>> user.followers.all() # 显示B(因为B是A的关注者)

请问如何根据related_name区分__str__方法的输出?有没有可行的方案?


解决方案

其实Django的模型实例本身无法直接感知它是通过哪个related_name被查询出来的,所以直接修改UserFollowing的__str__方法来适配不同调用场景是行不通的。不过我们可以换个思路,直接在CustomUser模型中添加快捷属性,让你直接获取对应的用户集合,而不是返回UserFollowing中间模型的实例。

方法1:添加@property属性直接返回用户对象

在你的CustomUser模型中添加以下代码:

class CustomUser(models.Model):
    # 你的其他字段...

    @property
    def following_users(self):
        # 获取当前用户关注的所有用户
        return CustomUser.objects.filter(followers__user=self)
    
    @property
    def follower_users(self):
        # 获取关注当前用户的所有用户
        return CustomUser.objects.filter(following__following_user=self)

这样调用的时候,你就可以直接拿到用户对象:

>>> user = CustomUser.objects.get(id=1)
>>> user.following_users.all() # 返回所有被该用户关注的CustomUser实例,显示它们的__str__
>>> user.follower_users.all() # 返回所有关注该用户的CustomUser实例,显示它们的__str__

方法2:如果一定要保留原related_name调用方式

如果你不想新增属性,还是想通过user.following.all()和user.followers.all()来获取用户对象,可以在调用时直接提取对应的用户字段:

# 获取当前用户关注的所有用户的用户名列表
user.following.values_list('following_user__username', flat=True)

# 获取当前用户关注的完整用户对象集合
CustomUser.objects.filter(id__in=user.following.values('following_user_id'))

对比下来,第一种方法(添加@property)的代码可读性更高,也更贴合你的使用需求。


内容的提问来源于stack exchange,提问作者SihwanLee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:45:51