For some reason my nested serializers are not displaying related data. I've searched online for an answer but cannot find any answers that fixes this issue. The demo apps I make using nested serializers work as expected, but on my main app the nested serializers do not display related data.
Below is my relevant code.
##models
...
class Location(models.Model):
user = models.ForeignKey(User, null=False, on_delete=models.CASCADE)
name = models.CharField("Full name", max_length=100,)
geolocation = models.PointField()
address1 = models.CharField("Address line 1", max_length=1024,)
address2 = models.CharField("Address line 2", null=True, max_length=1024,)
city = models.CharField("City", max_length=50,)
STATES = [
("AL", "Alabama"),
("AK", "Alaska"),
("AZ", "Arizona"),
("AR", "Arkansas"),
("CA", "California"),
("CO", "Colorado"),
("CT", "Connecticut"),
("DE", "Delaware"),
("FL", "Florida"),
("GA", "Georgia"),
("HI", "Hawaii"),
("ID", "Idaho"),
("IL", "Illinois"),
("IN", "Indiana"),
("IA", "Iowa"),
("KS", "Kansas"),
("KY", "Kentucky"),
("LA", "Louisiana"),
("ME", "Maine"),
("MD", "Maryland"),
("MA", "Massachusetts"),
("MI", "Michigan"),
("MN", "Minnesota"),
("MS", "Mississippi"),
("MO", "Missouri"),
("MT", "Montana"),
("NE", "Nebraska"),
("NV", "Nevada"),
("NH", "New Hampshire"),
("NJ", "New Jersey"),
("NM", "New Mexico"),
("NY", "New York"),
("NC", "North Carolina"),
("ND", "North Dakota"),
("OH", "Ohio"),
("OK", "Oklahoma"),
("OR", "Oregon"),
("PA", "Pennsylvania"),
("RI", "Rhode Island"),
("SC", "South Carolina"),
("SD", "South Dakota"),
("TN", "Tennessee"),
("TX", "Texas"),
("UT", "Utah"),
("VT", "Vermont"),
("VA", "Virginia"),
("WA", "Washington"),
("WV", "West Virginia"),
("WI", "Wisconsin"),
("WY", "Wyoming")
]
state = models.CharField(max_length=14, choices=STATES, default='AL')
zip_code = models.CharField("ZIP / Postal code", max_length=12,)
country = models.CharField("Country", max_length=3,)
website = models.URLField(max_length=200, null=True)
def _str_(self):
return self.name
class FavoriteLocation(models.Model):
nickname = models.CharField("Nickname", max_length=24,)
user = models.ForeignKey(User, related_name='user_details', null=False, on_delete=models.CASCADE)
location = models.ForeignKey(Location, related_name='location_details', null=False, on_delete=models.CASCADE)
def _str_(self):
return self.nickname
...
##serializers
...
class LocationSerializer(serializers.ModelSerializer):
class Meta:
model = Location
fields = ['id', 'geolocation', 'address1', 'address2', 'city', 'state', 'country', 'website']
class FavoriteLocationSerializer(serializers.ModelSerializer):
location_details = LocationSerializer(many=True, read_only=True)
class Meta:
model = FavoriteLocation
fields = ['id', 'nickname', 'user', 'location', 'location_details']
...
## viewset
...
class FavoriteLocationViewset(viewsets.ModelViewSet):
permission_class = (IsAuthenticated,)
queryset = FavoriteLocation.objects.all()
serializer_class = FavoriteLocationSerializer
...
## router
...
router.register(r'favoritelocation', FavoriteLocationViewset, basename='favorite_locations')
...
This is the output I am getting in my json response.
[
{
"id": 2,
"nickname": "My Favorite Restaurant",
"user": 2,
"location": 2
}
]
What is making the nested serializers not display properly?
Thank you so much for help.
I've created demo apps that use nested serializers with success, but trying to replicate it on my main app does not work. I'm able to see the foreign keys in the json response, and the "depth" option will show that there is data and the models are setup correctly. I've also tried adding 'related_name' on my model, but to no avail.
The problem is because of how you are using nested serialization. So you should change the code inside of the FavoriteLocationSerializer
class like this:
class FavoriteLocationSerializer(serializers.ModelSerializer):
location_details = LocationSerializer(source='location')
class Meta:
model = FavoriteLocation
fields = ['id', 'nickname', 'user', 'location', 'location_details']
The type of location field is ForeignKey
which is a many-to-one relation, while you are adding many=True
flag which should be used if the field is used to represent a to-many relationship. (DRF documentation)
Read the Django document about related_name to understand its usage.
There is no need to set read_only=True
, because by default nested serializers are read-only. (DRF documentation)
You should use source
attribute when the name of item you want to serialize is not same as its name inside the model serializer.