em1208/adrf

The nested ModelSerialzier runs the synchronization code with a ForeignKey

Opened this issue · 3 comments

Version:
adrf == 0.1.8
djangorestframework == 3.15.2

class ModelA(models.Model):
    xxx

class ModelB(models.Model):
    fielda = models.ForeignKey(ModelA)

class SerializerA(serializers.ModelSerializer):
    xxxx

class SerializerB(serializers.ModelSerializer):
    fielda = SerializerA()
serializer = SerialzierB(queryset, many=True)
serializer_data = await serializer.adata

Will call the synchronization code to get instance A and then raise it
django.core.exceptions.SynchronousonlyOperation: You cannot call this from an async context

The problem seems to be here. If it is a foreign key, this will not be asynchronous

attribute = field.get_attribute(instance)

temporary solution

A: Using select_related
B:
This will work, but I'm not too deep into performance and core

attribute = await sync_to_async(field.get_attribute)(instance)

@em1208 I tested this

attribute = await sync_to_async(field.get_attribute)(instance)

and it worked on my end. the issue is that nested serializers ie in this issue, are run sync'ed, so you'll get the django async issue.
Is it possible to merge this?

Facing same issue. adding sync_to_async solved it. Can we merge this please?
@em1208