I am trying to serialize related models for an API view.
class Dashboard(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)
user = models.ForeignKey(IamUser, on_delete=models.CASCADE, related_name='dashboards')
title = models.CharField(max_length=100)
type = models.CharField(max_length=100)
position = models.IntegerField()
config = models.CharField(max_length=5000, blank=True, null=True)
class WidgetLayout(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)
user = models.ForeignKey(IamUser, on_delete=models.CASCADE, related_name='widgets')
dashboard = models.ForeignKey(Dashboard, on_delete=models.CASCADE, related_name='widgets')
type = models.ForeignKey(Widget, on_delete=models.CASCADE)
position = models.IntegerField()
width = models.IntegerField()
config = models.CharField(max_length=5000, blank=True, null=True)
with the following serializers
class WidgetLayoutSerializer(serializers.ModelSerializer):
class Meta:
model = WidgetLayout
fields = ['id', 'type', 'position', 'width', 'config']
class DashboardSerializer(serializers.ModelSerializer):
class Meta:
widgets = WidgetLayoutSerializer(many=True)
model = Dashboard
fields = ['id', 'title', 'position', 'config', 'type', 'widgets']
The view calls the serializers like this:
dashboards = request.user.dashboards.all()
serializer = DashboardSerializer(dashboards, many=True)
The expected output would be a list of Widgets in their JSON serialization for each Dashboard, however, I get only a list of Widget-IDs. I discovered that, if i remove the widgets = WidgetLayoutSerializer(many=True)
, the result is the same, so I suspect, the serializer is not being used or referenced properly. I went through https://www.django-rest-framework.org/api-guide/relations/#example and tried to spot any difference, but could not find it.
Adding the prefetch_related for the widgets to the .all() in the view made no difference.
depth=1 is not really helpful, as I want to specify each serializer explicitly.
CodePudding user response:
This is definitely not correct that 2 fields have the same related_name:
user = models.ForeignKey(IamUser, on_delete=models.CASCADE, related_name='widgets')
dashboard = models.ForeignKey(Dashboard, on_delete=models.CASCADE, related_name='widgets')
Remove widgets
from user
.
Also the field should be a base class property, not a Meta
class property.
class DashboardSerializer(serializers.ModelSerializer):
widgets = WidgetLayoutSerializer(many=True)
class Meta:
model = Dashboard
fields = ['id', 'title', 'position', 'config', 'type', 'widgets']
Everything else seems good for me.