Reputation: 9153
I'm working with serializers as described by the link:Serializer relations (section PrimaryKeyRelatedField)
I have a slight different need, I'm sure it's really easy.
class Album(models.Model):
album_name = models.CharField(max_length=100)
artist = models.CharField(max_length=100)
class Track(models.Model):
album = models.ForeignKey(Album, related_name='tracks')
order = models.IntegerField()
title = models.CharField(max_length=100)
duration = models.IntegerField()
class SomeWidget(models.Model):
album = models.ForeignKey(Album)
track = models.ForeignKey(Track)
name = models.CharField(max_length=100)
description = models.CharField(max_length=100)
My need, I need to return the following:
{
'album_name': 'Things We Lost In The Fire',
'artist': 'Low',
'tracks': [
'1: Sunflower',
'2: Whitetail',
'3: Dinosaur Act',
...
],
'widget': [
{
'id': '1234',
'name': 'my widget',
'description': 'my description'
}
]
}
I am trying:
class WidgetField(serializers.RelatedField):
def to_representation(self, value):
return {
'id': '1234'
....
}
class TrackListingField(serializers.RelatedField):
def to_representation(self, value):
...
class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackListingField(many=True)
widget = WidgetField()
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
I keep getting the error:
AssertionError: Relational field must provide a `queryset` argument, override `get_queryset`, or set read_only=`True`.
Thanks
Upvotes: 0
Views: 2560
Reputation: 9153
Ok, got it. It took a little bit of Googling / trial and error. Apparently you can override the function that returns data for the field.
For example:
class AlbumSerializer(serializers.ModelSerializer):
widget = serializers.SerializerMethodField()
def get_widget(self, data):
return {
'id': data.id
}
OR, you can do the following:
class WidgetSerializer(serializers.ModelSerializer):
class Meta:
model = Widget
fields = ('id', 'name', 'description',)
.... and in the AlbumSerializer.get_widget function:
def get_widget(self, data):
widget = Widget.objects.get(album=data.album, track=data.track)
return WidgetSerializer(widget, many=False, context=self.context).data
Finally, you don't have to use the function name "get_widget". You can name it whatever you want. Example:
class AlbumSerializer(serializers.ModelSerializer):
widget = serializers.SerializerMethodField("fn_override")
def fn_override(self, data):
....
You can follow the pattern in this SO question: Django REST Framework: adding additional field to ModelSerializer
Upvotes: 1