Include entire Foreign Key object when retrieving an object

Viewed 42

I'm currently trying to carry over object relationship functionality from a php backend to a python backend. In the php application you were able to have a call like so:

~api/v1/cats/5b40b6eb-538f-a015-9196-1cc63cf8d7ae

That would return a result like this:

{
    id: "5b40b6eb-538f-a015-9196-1cc63cf8d7ae",
    name: "mittens",
    hatId: "0845de76-9d68-cfee-0ebb-473ccddf16bc",
}

The functionality that I am trying to replicate is that if you added an include param to the call with the name of foreign object like this:

~api/v1/cats/5b40b6eb-538f-a015-9196-1cc63cf8d7ae?include=hat

Then it would return the original object including the foreign key object

{
    id: "5b40b6eb-538f-a015-9196-1cc63cf8d7ae",
    name: "mittens",
    hatId: "0845de76-9d68-cfee-0ebb-473ccddf16bc",
    hat: {
        id: "0845de76-9d68-cfee-0ebb-473ccddf16bc",
        name: 'top hat',
    }
}

All that I've come across so far is select_related, HyperlinkedRelatedField, and prefetch_related; none of these seem to be able to get the above result when implemented.

1 Answers

I would strongly recommend using Django Rest Framework, and specifically look at nested relationships.

The example given in the DRF docs matches what you're looking to do almost exactly (though note, it's a one-to-many field, while your example is a one-to-one field):

>>> album = Album.objects.create(album_name="The Grey Album", artist='Danger Mouse')
>>> Track.objects.create(album=album, order=1, title='Public Service Announcement', duration=245)
<Track: Track object>
>>> Track.objects.create(album=album, order=2, title='What More Can I Say', duration=264)
<Track: Track object>
>>> Track.objects.create(album=album, order=3, title='Encore', duration=159)
<Track: Track object>
>>> serializer = AlbumSerializer(instance=album)
>>> serializer.data
{
    'album_name': 'The Grey Album',
    'artist': 'Danger Mouse',
    'tracks': [
        {'order': 1, 'title': 'Public Service Announcement', 'duration': 245},
        {'order': 2, 'title': 'What More Can I Say', 'duration': 264},
        {'order': 3, 'title': 'Encore', 'duration': 159},
        ...
    ],
}
Related