Получить объекты пользователя из внешнего ключа - PullRequest
0 голосов
/ 26 августа 2018

Я использую 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, который будет возвращать всех подписчиков, которые есть у пользователя.Однако я не хочу, чтобы он возвращался в формате модели 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 в качестве заполнителя только для проверки.

1 Ответ

0 голосов
/ 26 августа 2018

вы должны использовать сериализатор для 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, ваш <code>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 является текущим аутентифицированным пользователем (по крайней мере, в одной из его целей).

обновлено

также измените ваш URL-адрес на что-то вроде этого:

path('/api/followers/<username>/', FollowingAPIView.as_view(), name='get_user_followers')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...