Suppose i have two models:
class Region(models.Model):
region_name = models.CharField(
max_length=50, null=False, blank=False, unique=True, verbose_name="Region Name"
)
def __str__(self):
return self.region_name
class Meta:
verbose_name_plural = "Regions"
class Country(models.Model):
region_id = models.ForeignKey(
Region,
null=True,
blank=True,
on_delete=models.CASCADE,
verbose_name="Region id",
)
country_name = models.CharField(
max_length=50, unique=True, null=False, blank=False, verbose_name="Country Name"
)
def __str__(self):
return self.country_name
class Meta:
verbose_name_plural = "Countries"
Now, when i access the country model through Djnago REST Framework, as /api/countries
I get country_name and region_id for example
[
{
"id": 1,
"country_name":"Taiwan",
"region_id": 1
},
...
...
]
Is there any way to get the result like:
[
{
"id": 1,
"country_name":"Taiwan",
"region_id": {
id: 1,
region_name: "Asia",
}
},
...
...
]
I have tried nested serializer example as on the DRF website, but it returns a list of countries if we get the regions api.
like:
[
{
"id": 1,
"region_name":"Asia",
"countries":
[
"Taiwan",
"Japan",
"Vietnam",
...
]
},
...
...
]
I need to know the region name of the country in one api get request. Right now i am using 2 requests. One to get country, and then get region name from region id.
This is my model and serializer if i use nested serializer.
class Region(models.Model):
region_name = models.CharField(
max_length=50, null=False, blank=False, unique=True, verbose_name="Region Name"
)
def __str__(self):
return self.region_name
class Meta:
verbose_name_plural = "Regions"
class Country(models.Model):
region_id = models.ForeignKey(
related_name="countries"
Region,
null=True,
blank=True,
on_delete=models.CASCADE,
verbose_name="Region id",
)
country_name = models.CharField(
max_length=50, unique=True, null=False, blank=False, verbose_name="Country Name"
)
class CountrySerializer(serializers.ModelSerializer):
class Meta:
model = Country
fields = "__all__"
class RegionSerializer(serializers.ModelSerializer):
countries = serializers.SlugRelatedField(
many=True,
read_only=True,
slug_field='country_name'
)
class Meta:
model = Region
fields = ["id", "region_name", "countries"]
The reason you only get the slugs of the related Countrys is because you use the SlugRelatedField, that will thus list the slugs of the Countrys.
The trick is to make extra serializers that will serializer the related object(s). For example:
class ShallowRegionSerializer(serializers.ModelSerializer):
class Meta:
model = Region
fields = '__all__'
class CountrySerializer(serializers.ModelSerializer):
region_id = ShallowRegionSerializer()
class Meta:
model = Country
fields = '__all__'
class CountryRegionSerializer(serializers.ModelSerializer):
class Meta:
model = Country
fields = '__all__'
class RegionSerializer(serializers.ModelSerializer):
countries = CountryRegionSerializer(
many=True,
read_only=True
)
class Meta:
model = Region
fields = ['id', 'region_name', 'countries']
Now you can make use of the CountrySerializer and the RegionSerializer. When serializing objects, it will use other serializers, like the ShallowRegionSerializer and CountryRegionSerializer to serialize related object(s).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With