70👍
You can use SerializerMethodField
and write custom method for this.
class AlbumSerializer(HyperlinkedModelSerializer):
song_set = serializers.SerializerMethodField()
class Meta:
model = Album
fields = [
'pk',
'timestamp',
'song_set'
]
def get_song_set(self, instance):
songs = instance.song_set.all().order_by('-timestamp')
return SongListSerializer(songs, many=True).data
62👍
Add ordering meta parameter to your Song model:
class Song(models.Model):
album = models.ForeignKey('album.Album', default=1)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
class Meta:
ordering = ['timestamp', 'pk']
- [Django]-Retrieving parameters from a URL
- [Django]-Sending HTML email in django
- [Django]-Django custom management commands: AttributeError: 'module' object has no attribute 'Command'
31👍
In your ViewSet
, you can specify a queryset with a custom Prefetch
object that you can filter and order as you like. Prefetching causes just one additional database query (instead of one per parent object when using SerializerMethodField
), giving vastly improved performance.
from rest_framework import viewsets
from django.db.models import Prefetch
class AlbumViewSet(viewsets.ModelViewSet):
queryset = Album.objects.prefetch_related(Prefetch('song_set',
queryset=Song.objects.order_by('-timestamp')))
- [Django]-How to know current name of the database in Django?
- [Django]-How to TRUNCATE TABLE using Django's ORM?
- [Django]-Python Django Gmail SMTP setup
7👍
Old thread, but because it’s still popping up on Google I want to share my answer as well. Try overwriting the Serializer.to_representation
method. Now you can basically do whatever you want, including customising the sorting of your response. In your case:
class AlbumSerializer(HyperlinkedModelSerializer):
song_set = SongListSerializer(many=True, read_only=True)
class Meta:
model = Album
fields = [
'pk',
'timestamp',
'song_set'
]
def to_representation(self, instance):
response = super().to_representation(instance)
response["song_set"] = sorted(response["song_set"], key=lambda x: x["timestamp"])
return response
- [Django]-Separation of business logic and data access in django
- [Django]-ImproperlyConfigured: The included urlconf <project>.urls doesn't have any patterns in it
- [Django]-How do you log server errors on django sites
1👍
Another way to solve this is to modify the to_representation
method on the ListSerializer
to change the ordering when the relationship is queried via the ORM.
This to_representation
is similar to how it works for the base ListSerializer
in DRF.
class SongListSerializer(HyperlinkedModelSerializer):
class Meta:
model = Song
fields = [
'pk',
'timestamp'
]
def to_representation(self, data):
iterable = data.all().order_by('-timestamp', '-id') \
if isinstance(data, models.Manager) else data
return [self.child.to_representation(item) for item in iterable]
class AlbumSerializer(HyperlinkedModelSerializer):
song_set = SongListSerializer(many=True, read_only=True)
class Meta:
model = Album
fields = [
'pk',
'timestamp',
'song_set'
]
- [Django]-Custom Filter in Django Admin on Django 1.3 or below
- [Django]-Use variable as dictionary key in Django template
- [Django]-Add additional options to Django form select widget