我正在尝试使用查询检查是否存在以下关系。首先,获取用户拥有的所有关注者,然后检查用户是否关注那些关注者。这是我的模特:
class Following(models.Model):
target = models.ForeignKey('User', related_name='followers', on_delete=models.CASCADE, null=True)
follower = models.ForeignKey('User', related_name='targets', on_delete=models.CASCADE, null=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '{} is followed by {}'.format(self.target, self.follower)
class User(AbstractBaseUser):
username = models.CharField(max_length=15, unique=True)
email = models.EmailField(max_length=100, unique=True)
我正在使用Django Rest-Framework,所以我转到特定的URL以获取所需的信息。转到URL后,将得到预期的输出。我得到了用户拥有的所有关注者。
views.py
class GetFollowersView(ListAPIView):
serializer_class = FollowingSerializer
def get_queryset(self):
requested_user = get_requested_user(self)
return User.objects.filter(targets__target=requested_user).order_by('-targets__created_at'). \
annotate(is_following=Count('followers__follower', filter=Q(followers__follower=requested_user), distinct=True))
def get_requested_user(self):
filter_kwargs = {'username': self.kwargs['username']}
return get_object_or_404(User.objects.all(), **filter_kwargs)
serializers.py
class FollowingSerializer(serializers.ModelSerializer):
is_following = serializers.IntegerField()
class Meta:
model = User
fields = ('id', 'username', 'follower_count', 'following_count', 'is_following')
但是,问题出在is_following
批注中。我想看看用户是否关注每个特定的关注者。如果他们关注该关注者,则is_following
应该为1,否则为0。我在is_following
中得到不正确的结果,我可以通过这种方式检查用户是否关注每个特定的关注者?
答案 0 :(得分:0)
如果您已安装Django Debug Toolbar,并检查查询中当前过滤器/注释的内容,则显示为(对于单个用户)
SELECT "user"."id", "user"."username", "user"."email",
COUNT(DISTINCT T4."follower_id") AS "is_following" FROM "user"
INNER JOIN "following" ON ( "user"."id" = "following"."follower_id" )
LEFT OUTER JOIN "following" T4 ON ( "user"."id" = T4."target_id" )
WHERE "following"."target_id" = 4 GROUP BY "user"."id", "user"."username",
"user"."email", "following"."created_at" ORDER BY "following"."created_at"
DESC
但是要获得所选用户所关注的用户数,您确实想要类似
SELECT ue."id", ue."username", ue."email", COUNT(DISTINCT fe."target_id") AS
"is_following" FROM "user" u inner JOIN "following" fe ON ( u."id" =
fe."follower_id" ) inner join user ue on fe.target_id = ue.id and u.id = 4
GROUP BY ue."id", ue."username", ue."email"
我认为不可能像您一样在同一查询中同时合并关注者和被关注者。您可能会找到路口,然后从那里开始...这样的事情。
def get_queryset(self):
username = self.request.query_params.get('username', None)
requested_user = models.User.objects.get(username=username)
following_me = models.User.objects.filter(targets__target=requested_user).order_by('-targets__created_at')
i_follow = models.User.objects.filter(followers__follower=requested_user).order_by('-followers__created_at')
common = following_me & i_follow
### Set is_following for common as 1, all others as 0.
#......
#......
return following_me
答案 1 :(得分:0)
为什么不使用M2M关系?看起来像这样简单:
from django.db import models
class User(models.Model):
name = models.CharField(max_length=200)
followers = models.ManyToManyField('User')
@property
def follower_count(self):
# How many people follow me
return len(self.followers)
@property
def followee_count(self):
# How many people I follow
return len(self.user_set.all())
您可以修改get_queryset()
以仅找到关注者:
User.objects.filter(followers__contains=self.request.user)
有帮助吗?