Using the same serializer field as PrimaryKeyRelatedField for write and as NestedSerializer Field for read

4,724 views
Skip to first unread message

Kaviraj Kanagaraj

unread,
Sep 2, 2015, 12:09:04 PM9/2/15
to Django REST framework
Hi Everyone,

Conside the following case

class Album(models.Model):
     name = models.CharField(max_length=20)

class Track(models.Model):
     album = models.ForeignKey(Album, related_name='tracks')


I need to create TrackSerializer,

class TrackSeriallizer(serializers.ModelSerializer):
     class Meta:
          model = Track

Here by default, album field will be treated as PrimayKeyRelatedField. So the serialized data would some like

{
  'id': 1,
  'album':1
}

but I wanted to be 
{
  'id': 1,
  'album': {
                  'id': 1,
                  'name': 'album1'
                }
}

I am aware that I could use nested serializer as below to achive this, but then I cannot create Track instance just by passing album id 

class TrackSeriallizer(serializers.ModelSerializer):
     album = AlbumSerializer()
     class Meta:
          model = Track


Can I create a TrackSerializer, so that whenever I get a list of Tracks I wants Album for the track to be nested. But while creating a Track, I should be able to pass album as id(PrimaryKeyRelation)?

Help me figuring out. Thanks in advance

Kevin Brown

unread,
Sep 2, 2015, 12:24:11 PM9/2/15
to Django REST framework
It's probably possible to do this, but usually I would recommend just having two separate fields (as covered in this Stack Overflow answer). One holds the primary key (can be write-only) and the other is the nested serializer (usually read-only).

Most of the alternatives either require a lot of work (overriding `to_internal_value`) or result in inconsistent responses (custom serializer).

--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-fram...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Kaviraj Kanagaraj

unread,
Sep 4, 2015, 4:48:14 AM9/4/15
to Django REST framework
@Kevin Thanks for your help.

I have solved this by following way,

class TrackSeriallizer(serializers.ModelSerializer):
     album = AlbumSerializer(read_only=True)
     album_id = serializers.PrimaryKeyRelatedField(queryset=Album.objects.all(), write_only=True, source='album')

     class Meta:
          model = Track

Now during listing of Tracks 'album' field will be used as nested serializer, And during create, album_id is used with source  'as album'. So that I can just pass the album_id during creation. 'source' attribute of the serializer solves the problem
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+unsub...@googlegroups.com.

Mingda Zhao

unread,
Jul 15, 2018, 9:16:35 AM7/15/18
to Django REST framework
THIS IS FREAKING MAGIC

Joel Kumwenda

unread,
Aug 7, 2018, 10:59:28 PM8/7/18
to Django REST framework
This is smart solution, works like a charm.
Reply all
Reply to author
Forward
0 new messages