Используйте get_object_or_404, чтобы получить только одно поле, а не все поля, указанные в модели в django rest framework? - PullRequest
0 голосов
/ 31 января 2020

Я пытаюсь получить только одно поле в результате get_object_or_404, но, похоже, оно не работает для меня.

Я использую модель User из приложения аутентификации по умолчанию django. Это мой сериализатор:

class UserSerializer(serializers.Serializer):
    username = serializers.CharField(max_length=150)
    email = serializers.EmailField(max_length=254)
    first_name = serializers.CharField(max_length=30)

Это мой взгляд:

class UserView(APIView):

    def get(self, request, id=None):

        if id:
               data = 
               get_object_or_404(User.objects.only('username'), 
               id=id)
            serializer = UserSerializer(data, many=False)
            return Response(serializer.data)
        else:
                data = get_list_or_404(User)
            serializer = UserSerializer(data, many=True)
            return Response(serializer.data)

Даже после использования этого get_object_or_404(User.objects.only('username'), id=id) я все равно получаю все поля, указанные в сериализаторе, а не только username.

Это ответ, который я получаю, когда передаю идентификатор в API при вызове его от почтальона.

{
    "username": "admin",
    "email": "admin@email.com",
    "first_name": ""
}

вместо этого:

{
    "username": "admin",
}

1 Ответ

2 голосов
/ 31 января 2020

Из do c из get_object_or_404

Звонки get() на данного менеджера модели, но он вызывает Http404 вместо исключения DoesNotExist модели.

Не нужно ожидать, что он вернет только одно значение .


Решение

удалить другие поля, отличные от username, из вашего сериализатора

class UserSerializer(serializers.Serializer):
    username = serializers.CharField(max_length=150)

Чем больше обобщений c решение было бы, использовать два разных сериализатора для обеих целей

# serializers.py
class <b>UserListSerializer</b>(serializers.Serializer):
    username = serializers.CharField(max_length=150)
    email = serializers.EmailField(max_length=254)
    first_name = serializers.CharField(max_length=30)


class <b>UserGetSerializer</b>(serializers.Serializer):
    username = serializers.CharField(max_length=150)


# views.py
class UserView(APIView):

    def get(self, request, id=None):
        if id:
            <b>user_instance = get_object_or_404(User, id=id)
            serializer = UserGetSerializer(user_instance)  # used `UserGetSerializer`</b>
            return Response(serializer.data)
        else:
            <b>user_qs = get_list_or_404(User)
            serializer = UserListSerializer(user_qs, many=True)  # used `UserListSerializer`</b>
            return Response(serializer.data)

Здесь я создал два класса сериализатора, UserListSerializer и UserGetSerializer и использовали их в поле зрения.

...