-
Notifications
You must be signed in to change notification settings - Fork 44
Open
Description
Lines 178 to 181 in 697ebf0
| if isinstance(data, models.query.QuerySet): | |
| return [await self.child.ato_representation(item) async for item in data] | |
| else: | |
| return [await self.child.ato_representation(item) for item in data] |
When using the default ListSerializer, it calls
ato_representation on each item and awaits them one at a time. And that kind of behavior might not be very useful when dealing with a list of async serializers.
The problem I have in my project, is that I have a serializer, which makes an HTTP request, and then I have a list of those serializers:
class ItemSerializer(AsyncSerializer):
makes_a_request = SerializerMethodField()
async def get_makes_a_request(self):
return await function_that_makes_a_request()
class ItemsSerializer(AsyncSerializer):
items = ItemSerializer(many=True)This results in each consecutive request waiting for the previous one to complete - basically the same as if I used synchronous serializers. Here's what I use in my project, to overcome this issue:
# Put this in the list_serializer_class field in the Meta class
class ParallelListSerializer(aserializers.ListSerializer):
async def ato_representation(self, data):
if isinstance(data, models.Manager):
data = data.all()
tasks = []
if isinstance(data, models.query.QuerySet):
tasks = [self.child.ato_representation(item) async for item in data]
else:
tasks = [self.child.ato_representation(item) for item in data]
return await asyncio.gather(*tasks)
# NOTE: acreate has the same problem in ListSerializerWouldn't it make sense to make this the default behavior? Although, someone might actually be relying on the current order of execution, in which case you could introduce a separate serializer for this (like the one above).
Metadata
Metadata
Assignees
Labels
No labels