5

I have a situation where a model has a foreign key with details. Ex. there are two models

class Person(models):
    country = models.ForeignKey(Country)

class Country(models):
    name = models.CharField(max_length=100)

Assume countries have been created beforehand. Now, I want the APIs for Person to take only country Id in POST/PUT requests but return the details of that country instead of only Id.

Request
{
   "id": 1,
   "country": 9
}
Response
{
   "id": 1,
   "country": {
       "id": 9,
       "name": "Some Country"
    }
}

I'm using Django Rest Framework. (I can write serializers which either take id in both read and write APIs or take the entire country object)

Rubbal
  • 779
  • 7
  • 19
  • I actually implemented it in the same way after going through some github discussion. I created a country and country_detail field, the latter of which is read only and shows the detail. – Rubbal Jul 11 '17 at 11:14
  • you can use _HyperlinkedModelSerializer_ on Country Serializer and also make sure to add the _HyperlinkedRelated_ field in Country so that a Country have all the detail links to the person in current Country. Also go through the documentation on this [topic](http://www.django-rest-framework.org/api-guide/relations/#hyperlinkedrelatedfield). Hope it helps you ! – Mirza715 Jul 14 '17 at 06:58

1 Answers1

1

You can write custom field CountryField for this and user to_representation method to return object details:

class CountryDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = Country
        fields = ('id', 'name')

class CountryField(serializers.PrimaryKeyRelatedField):
    def to_representation(self, value):
        country = models.Barcode.objects.get(pk=value.pk)
        serializer = CountryDetailSerializer(country)
        return serializer.data

    def get_queryset(self):
        return Country.objects.all()

And use it in Person serializer:

class PersonSerializer(serializers.ModelSerializer):
    country = CountryField()
neverwalkaloner
  • 46,181
  • 7
  • 92
  • 100