Open famdude opened 8 months ago
@famdude you need to change def to_representation
to async def ato_representation
However there is a different issue, this works:
async def ato_representation(self, instance):
return { }
this throws 'SerializerMethodField' object has no attribute 'ato_representation':
async def ato_representation(self, instance):
representation = await super().ato_representation(instance)
return representation
I still can't find a way to make this work while calling the super.to_representation function
Got it to finally work with this (but it feels dirty): Disclaimer: I am new to Django & Python
class AsyncCompanySerializer(AsyncModelSerializer):
class Meta:
model = Company
fields = ['id', 'name']
class AsyncNoorUserSerializer(AsyncModelSerializer):
companies = serializers.SerializerMethodField()
class Meta:
model = NoorUser
fields = ['id', 'username', 'preferred_lang', 'companies']
async def get_companies(self, obj):
roles = await sync_to_async(list)(Role.objects.filter(user=obj).select_related('company').all())
companies = await AsyncCompanySerializer([role.company for role in roles], many=True).adata
return companies
async def ato_representation(self, instance):
representation = super().to_representation(instance)
representation['companies'] = await representation['companies']
return representation
@famdude This is the only way it worked for me but feels wrong:
class AsyncUserSerializer(AsyncModelSerializer):
companies = serializers.SerializerMethodField()
class Meta:
model = User
fields = ['id', 'username', 'preferred_lang', 'companies']
async def get_companies(self, obj):
roles = await sync_to_async(list)(Role.objects.filter(user=obj).select_related('company').all())
companies = await AsyncCompanySerializer([role.company for role in roles], many=True).adata
return companies
async def ato_representation(self, instance):
representation = super().to_representation(instance)
representation['companies'] = await representation['companies']
return representation
@KShoukry The issue is that SerializerMethodField
does not currently support async methods, so if you instead define def get_companies(self, obj)
it will work without having to override async def ato_representation
. I hope this helps!
@em1208 That's not the solution! I NEED to override to_represetation
or ato_representation
, because I have some essential calculations to do there.
what do you mean by "SerializerMethodField
does not currently support async methods"? you mean django has not supported it yet? the method is a drf method, not a django method.
@famdude SerializerMethodField
is a Django Rest Framework field and not everything in DRF is currently supported by adrf in an async way. If you still require your SerializerMethodField
to be async then you can follow the solution https://github.com/em1208/adrf/issues/27#issuecomment-1886753489 because the value returned by the method needs to be manually awaited.
@em1208 hello, thank you and all the contributors for the hard work you've done! I saw the codebase and just wanted to ask if it is safe to use ModelViewSet
, permissions
, filters
, serializers
... for production, how well do they support async mode?
@lybrain Thanks for your kind words. It's is safe to use adrf
for production and you can verify the source code yourself but as mentioned adrf
does not support everything that Django Rest Framework provides in an async way so it depends on your requirements if it will be useful to you.
@em1208 As I really need it, I want to know do you have any plan to implement it? or other contributors should look at it?
@famdude no plan at the moment. Happy to review a PR for that.
I have a ModelSerializer that contains some
SerializerMethodField
s and I need to override theto_representation
method as well. for instance:this is the
APIView
I have:but I get this error:
'SerializerMethodField' object has no attribute 'ato_representation'