我正在使用Django Rest Framework。我有两个模型,如下所示:
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)
我想拥有一个API,该API将返回用户拥有的所有关注者。但是,我不希望以Following
模型格式返回它,我希望以这种格式将关注者作为用户返回:
[
{
"username": Bob,
"email": example@example.com
},
{
"username": Charlie,
"email": example@example.com
}
]
现在,我有这样的东西:
class FollowingAPIView(ListAPIView):
serializer_class = FollowingSerializer
def get_queryset(self):
return Following.objects.filter(target=3)
class FollowingSerializer(serializers.ModelSerializer):
class Meta:
model = Following
fields = ('follower', 'target')
这仅显示follower
和target
我不想要这个。我需要来自User
的实际数据。此外,我将target=3
用作占位符只是为了进行测试。
答案 0 :(得分:5)
您应该为User
而不是following
使用序列化程序:
class UserSerializer(serializers.ModelSerializer):
is_following = serializer.IntegerField()
class Meta:
model = User
fields = ('username', 'email', 'is_following')
另外,在视图中更改查询集,如下所示:
from django.db import models
from rest_framework.generics import get_object_or_404
class FollowingAPIView(ListAPIView):
serializer_class = FollowingSerializer
### so add this method to get the requested user based on the username in the url
def get_requested_user(self):
##get the user based on the user name in url
filter_kwargs = {'username': self.kwargs['username']}
obj = get_object_or_404(User.objects.all(), **filter_kwargs)
return obj
def get_queryset(self):
requested_user = self.get_requested_user()
return User.objects.filter(targets__target=requested_user)\
.annotate(is_following=models.Count('followers', filter=models.Q(followers__follower=requested_user), distinct=True))
如果您使用的是Django <2.0,则您的get_queryset
应该类似于:
def get_queryset(self):
requested_user = self.get_requested_user()
return User.objects.filter(targets__target=requested_user)\
.annotate(is_following=models.Count(models.Case(models.When(models.Q(followers__follower=requested_user), 1))))
因为要返回用户列表,而不是“跟随”实例。仅使用以下命令过滤(上述过滤器中的targets__
)用户target
中的Following
是当前经过身份验证的用户(至少在其目标之一中)。
已更新
另外,将您的网址更改为以下内容:
path('/api/followers/<username>/', FollowingAPIView.as_view(), name='get_user_followers')