Neeraj Kumar
Neeraj Kumar

Reputation: 3941

How to Show Foreign Key data in Django rest framework?

Model:

class Demo(models.Model):
    name = models.CharField(max_length=255)
    desc = models.TextField()
    user = models.ForeignKey('auth.User', on_delete=models.CASCADE)

Serializer:

class DemoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Demo
        fields = '__all__'

I have form in frontend side where I'm adding name, desc and assigning to User so here I'm getting on an issue.

I'm passing data to API {name: "demo", desc: "lorem ipsum", user: 1 } It's working on save but after saving it's return same response but I want user first_name, last_name, and email in return response.

Because I have a table showing a list of demo table content. but always getting only User ID not a detail of user.

If I'm increasing depth of Serializer It's creating an issue in save time but on get records time I'm getting all details of User model. Like Password also in response so that is a security issue for me show all thing.

Upvotes: 2

Views: 2343

Answers (2)

Usoof
Usoof

Reputation: 713

You can use depth = 1 to get all the data of foreign key object:

class DemoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Demo
        fields = '__all__'
        depth = 1

Upvotes: 4

mehamasum
mehamasum

Reputation: 5742

You could separate the Create and Retrieve serializer. For example, the create serializer will be the one you are currently using:

class DemoCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Demo
        fields = '__all__'

On the other hand, Retrieve serializer will serialize the User with a different serializer using Nested Relationship.

class DemoRetrieveSerializer(serializers.ModelSerializer):
    user = UserMinimalSerializer # or you could use your UserSerializer, see the last part of the answer
    class Meta:
        model = Demo
        fields = ('id', 'name', 'desc', 'user')
        read_only = ('id', 'name', 'desc', 'user',)

In your view, you will create the data with the first serializer and respond with the second. An example using APIView:

class DemoView(APIView):
    def post(self, request, format=None):
        create_serializer = DemoCreateSerializer(data=request.data)
        if create_serializer.is_valid():
            instance = create_serializer.save()
            retrive_serializer = DemoRetrieveSerializer(instance)
            return Response(retrive_serializer.data, status=status.HTTP_201_CREATED)
        return Response(create_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

You might have to customize DRF provided views to achieve this, i.e. for Generic views.

Since you don't want to include all the fields of User model, you will have to write a minimal representation of User using another serializer.

class UserMinimalSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'first_name', 'last_name', 'email')
        read_only = ('id', 'first_name', 'last_name', 'email',)

Hope it helps.

Upvotes: 1

Related Questions