Circular dependency in Django Rest Framework serializers
You should consider having a look at Specifying nested serialization in the Rest Framework documentation. The usage of depth
meta attribute enables you to retrieve related objects to the depth you set.
It is very convenient to avoid using serializers in both sides and thus having ImportError caused by cycles.
The default ModelSerializer uses primary keys for relationships, but you can also easily generate nested representations using the depth option:
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ['id', 'account_name', 'users', 'created']
depth = 1
you can do a local import of serializers like this:
class MySerializer(Serializer):
from app.core.serializers import AnotherSerializer
Do that in both of your imports. No need to use sys.modules
That is, as mentioned by Sebastian Wozny, that you don't have a logical circular dependancy
In my opinion your code is fine, because you do not have a logic circular dependency.
Your ImportError
is only raised because of the way import()
evaluates top level statements of the entire file when called.
However, nothing is impossible in python...
There is a way around it if you positively want your imports on top:
From David Beazleys excellent talk Modules and Packages: Live and Let Die! - PyCon 2015, 1:54:00
, here is a way to deal with circular imports in python:
try:
from images.serializers import SimplifiedImageSerializer
except ImportError:
import sys
SimplifiedImageSerializer = sys.modules[__package__ + '.SimplifiedImageSerializer']
This tries to import SimplifiedImageSerializer
and if ImportError
is raised, because it already is imported, it will pull it from the importcache.
PS: You have to read this entire post in David Beazley's voice.
Separating usual and nested serializers does the trick for me.
For your structure it will be something like:
Profiles app
# profiles/serializers/common.py
from images.serializers.nested import SimplifiedImageSerializer
class ProfileSerializer(SimplifiedProfileSerializer):
recent_images = SimplifiedImageSerializer(many=True)
And nested:
# profiles/serializers/nested.py
class SimplifiedProfileSerializer(serializers.Serializer):
name = serializers.CharField()
Images app
# images/serializers/common.py
from profiles.serializers.nested import SimplifiedProfileSerializer
class ImageSerializer(SimplifiedImageSerializer):
profile = SimplifiedProfileSerializer()
And nested:
# images/serializers/nested.py
class SimplifiedImageSerializer(serializers.Serializer):
title = serializers.CharField()