как получить Json отформатированный ответ на django - PullRequest
0 голосов
/ 14 февраля 2020

У меня есть пользовательская модель пользователя, и я реализовал систему слежения и слежения за пользователями, которая работает хорошо. Но проблема у меня заключается в том, что когда я запрашиваю подписчиков, которые есть у конкретного пользователя, полученный ответ JSON не совсем так, как я хочу, чтобы он возвращался. подробности ниже

модели

class User(AbstractBaseUser, PermissionsMixin):
    username = None
    email = models.EmailField(max_length=254, unique=True)
    name = models.CharField(max_length=250)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    last_login = models.DateTimeField(null=True, blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)
    slug = models.SlugField(max_length=255, unique=True, blank=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['name']

class FollowLog(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='followers')
    followed_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
                                    related_name='following', null=True)
    followed_on = models.DateTimeField(auto_now_add=True)
    status = models.CharField(choices=FOLLOW_STATUS, default=FollowStatus.following.value, max_length=30)
    updated_on = models.DateTimeField(auto_now=True)
    unfollowed_on = models.DateTimeField(null=True)
    blocked_on = models.DateTimeField(null=True)

сериализатор

class FollowerSerializer(serializers.ModelSerializer):
    '''
    Allows people to view follower of a user
    '''
    followed_by = serializers.SlugRelatedField(read_only=True, slug_field='slug')

    class Meta:
        model = FollowLog
        fields = ('followed_by',)
        read_only_fields = ('followed_by',)

представление

class UserFollowerView(APIView):
    '''
    Gets all the followers to a user
    '''
    permission_classes = [AllowAny]

    def get(self, request, slug):
        user = User.objects.get(slug=slug)
        followers = user.followers.all().filter(status='following').order_by("-followed_on")
        serializer = FollowerSerializer(followers, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

при запуске выше, я получаю соответствующий ответ но в этом формате

JSON ответ я получаю

[
    {
        "followed_by": "opeyemi-odedeyi-qqmunu13o4b8vd4"
    },
    {
        "followed_by": "modupeoluwa-odedeyi-m7ji5qj5szu2uqo"
    }
]

Я бы предпочел, чтобы я получил ответ, как показано ниже

предпочитаемый ответ, который я хочу получить

{
    "followed_by": [
        "opeyemi-odedeyi-qqmunu13o4b8vd4",
        "modupeoluwa-odedeyi-m7ji5qj5szu2uqo"
    ]
}

Ответы [ 2 ]

2 голосов
/ 14 февраля 2020

Сериализатор всегда будет возвращать словарь, а если вы установите many=true, он будет возвращать массив словарей.

Что вы можете сделать, это получить нужный массив из возвращенного массива словарей по сериализатору:

class UserFollowerView(APIView):
    '''
    Gets all the followers to a user
    '''
    permission_classes = [AllowAny]

    def get(self, request, slug):
        user = User.objects.get(slug=slug)
        followers = user.followers.all().filter(status='following').order_by("-followed_on")
        data = FollowerSerializer(followers, many=True).data
        data_to_return = list(map(lambda item: item['followed_by'], data))
        return Response(data_to_return, status=status.HTTP_200_OK)
1 голос
/ 14 февраля 2020

Вы можете сделать пользовательский рендер для вашего API и изменить формат ответа так, как вам хочется.

class UserFollowerView(APIView):
    '''
    Gets all the followers to a user
    '''
    permission_classes = [AllowAny]
    renderer_classes = (UserFollowerRenderer, )

    def get(self, request, slug):
        user = User.objects.get(slug=slug)
        followers = user.followers.all().filter(status='following').order_by("-followed_on")
        serializer = FollowerSerializer(followers, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

и рендерер может выглядеть примерно так: -

class UserFollowerRenderer(CoreJSONRenderer):
    charset = "utf-8"

    def render(self, data, media_type=None, renderer_context=None):
        if not data:
            return "[]"
        final_data = list()
        for element in data:
            final_data.append(element.get('followed_by'))
        result = dict(followed_by=final_data)
        return json_dumps(result)
...