0

I'm using Django 3.0 and I have a serializer using django-rest-framework. Let's say that for example I have a Forum object. Each forum has an owner that is a user.

In my GET /forums/ endpoint, I'd like to just have the owner_id. However, in my GET /forums/<forum_id>/ endpoint I'd like to return the entire embedded object.

Is there any way to have one serializer support both of these scenarios? If not, I would hate to have to make two serializers just to support this.

class ForumSerializer(serializers.ModelSerializer, compact=True):

    if self.compact is False:
        owner = UserSerializer(source='owner', read_only=True)
    else:
        owner_id = serializers.UUIDField(source='owner_id')
    ...
    How can I achieve this compact thing?

    class Meta:
        fields = [...]
        read_only_fields = ['owner', 'owner_id']
aroooo
  • 4,726
  • 8
  • 47
  • 81
  • What about this, https://stackoverflow.com/questions/29950956/drf-simple-foreign-key-assignment-with-nested-serializers/52246232#52246232 – JPG Mar 10 '20 at 08:42

2 Answers2

2

You can add a SerializerMethodField like this:

class ForumSerializer(serializers.ModelSerializer):

    owner = serializer.SerializerMethodField()

    def get_owner(self, obj):
       if self.context['is_compact'] == True:
           return obj.owner.pk
       else:
           return UserSerializer(obj.owner).data

    class Meta:
        model = YourModel
        fields = '__all__'


# Usage in view

serializer = ForumSerializer(context={'is_compact':True})

I am passing is_compact value through serializer's extra context.

ruddra
  • 50,746
  • 7
  • 78
  • 101
0

create two serializer classes

class ForumSerializerId(ModelSerializer):
     class Meta:
          model = Forum
          fields = ['forum_id']

class ForumSerializerDetail(ModelSerializer):
     class Meta:
          model = Forum

on your view.py

forums(request):
   forum_list = Forum.objects.all()
   forum_serializer = ForumSerializerId(forum_list,many=True) 
   return Response({"form":forum_serializer.data})

forum_detail(request,pk):
   forum = get_object_or_404(Forum,pk)
   forum_serializer = ForumSerializerDetail(forum)
   return Response({"form":forum_serializer.data})