Abdulmoiz Ahmer
Abdulmoiz Ahmer

Reputation: 2351

Use get_object_or_404 to get only one field rather than all fields specified in model in django rest framework?

I am trying to get just one field as a result from get_object_or_404 but it is not seem to be working for me.

I am using the User model from the default auth app of django. This is my serializer:

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

This is my view:

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)

Even after using this get_object_or_404(User.objects.only('username'), id=id) I am still getting all the fields specified in the serializer rather than just the username.

This is the response i get when i pass an id to the api while calling it from the postman.

{
    "username": "admin",
    "email": "[email protected]",
    "first_name": ""
}

rather than this:

{
    "username": "admin",
}

Upvotes: 0

Views: 8969

Answers (1)

JPG
JPG

Reputation: 88499

From the doc of get_object_or_404

Calls get() on a given model manager, but it raises Http404 instead of the model’s DoesNotExist exception.

You don't need to expect it would return only a single value.


Solution

remove other fields than the username from your serializer

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

The more generic solution would be, Use two different serializers for both purposes

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


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


# views.py
class UserView(APIView):

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

Here I created two serializer classes, UserListSerializer and UserGetSerializer and used them in view.

Upvotes: 5

Related Questions