1👍
You can use SerializerMethodField and provide custom serialization logic there:
class EventSerializer(serializers.Serializer):
events = serializers.SerializerMethodField(source="get_events")
def get_events(self, events):
event_list = {}
return [event_list[e.type].add({e}) if event.type in event_list else event_list[event.type] = [] for event in events]
0👍
I had a model similar to the following:
class Book(models.Model):
title = models.CharField(max_length=200)
class Author(models.Model):
name = models.CharField(max_length=200)
books = models.ManyToManyField(Book)
The JSON that was being generated for an Author
looks like this:
{
"name": "Sir Arthur C. Clarke",
"books": [
{
"title": "Rendezvous with Rama",
},
{
"title": "Childhood's End",
}
]
}
In the JSON wanted the books to be sorted by title. Since the books are pulled into the queryset via a prefetch_related
adding an order_by
to the View’s queryset had no effect (generated SQL didn’t have a join to the Books table). The solution I came up with was to override the get
method. In my version of the get
method, I have the super class generate the Response
and I modify it’s data (a Python dict
) before returning it as shown below.
I’m not too worried about performance for two reasons:
- because of the
prefetch_related
the join is already being done in Python rather than in the database - In my case the number of
Book
s perAuthor
is relatively small
class AuthorView(RetrieveUpdateAPIView):
queryset = Author.objects.prefetch_related(
'books',
)
serializer_class = AuthorSerializer
def get(self, request, *args, **kwargs):
response = super().get(request, *args, **kwargs)
def key_func(book_json):
return book_json.get('title', '')
books = response.data.get('books', [])
books = sorted(books, key=key_func)
response.data['books'] = books
return response
Source:stackexchange.com