0

I am using Django Rest Framework for a project and I have a nested serializer like this:

class TopSerializer(serializers.ModelSerializer):
    contact = (something goes here)
    email = (something goes here)

For POST, PATCH, PUT, DELETE I want to specify these values with a slug. Suppose each class (Contact, Email) has a member called resource_id and that is my slug. For these methods I could use:

class TopSerializer(serializers.ModelSerializer):
    contact = serializers.SlugRelatedField(read_only=False, slug_field='resource_id')
    email = serializers.SlugRelatedField(read_only=False, slug_field='resource_id')

However, for GET I want to return the embedded objects too, so I could use:

class TopSerializer(serializers.ModelSerializer):
    contact = ContactSerializer(read_only=True)
    email = EmailSerializers(read_only=True)

So how do I specify in my serializer that contact can be either a slug or a serialized object? Is there a way to do this with just one serializer or must I have two different serializers and use the request.method in the view to select which serializer I use?

Or, should I use something like this:

class TopSerializer(serializers.ModelSerializer):
    contact = ContactSerializer(read_only=True)
    email = EmailSerializers(read_only=True)
    contact_rid = serializers.SlugRelatedField(read_only=False,slug_field=resource_id,queryset=models.Contact.objects.all())
    email_rid = serializers.SlugRelatedField(read_only=False,slug_field=resource_id,queryset=models.Email.objects.all())

This way I can use contact_rid and email_rid for POST/PATCH/PUT/DELETE and get contact and email fields back in GET.

Am I on the right track? Other suggestions?

uedemir
  • 1,654
  • 1
  • 12
  • 21
Marc
  • 3,386
  • 8
  • 44
  • 68

2 Answers2

0

Check out custom fields https://www.django-rest-framework.org/api-guide/fields/#custom-fields You could define a custom serializer fields that overrides serializers.Field and overrride to_representation to return the fully serialized object and to_internal_value to mimic the behavior of a slugRelatedField.

Sam Sunde
  • 151
  • 7
0

You are on the right track!

Use one related field for write and another to read the full object is a good approach if you need more details for related objects.

You can also add to the slug field the flag write_only=True if you want the field is used only for write. However, checking this option will not hint selected objects when you are under an update route in Browseable API

Check this anwser

Lucas Weyne
  • 1,107
  • 7
  • 17