Recently, I was developing a Django project and it worked perfectly with manage.py runserver but when run through Gunicorn it was failing with an ImportError.
This really got me worked up – as a programmer, I hate when I don’t understand why something would work in one environment but fail in another.
The problem was circular import in Python!
I had two apps in this project: news and comments. News had the following model:
import comments.models
class Article(Model):
...
...
def get_root_comment(self):
try:
root = comments.models.Comment.objects.get(article=self, level=0)
except:
root = comments.models.Comment.objects.create(article=self, body=self.title)
return root
Comments had something like this:
from news.models import Article
class Comment(MPTTModel, TimeStampedModel):
....
article = models.ForeignKey(Article, related_name='comments')
This worked perfectly well with Django’s built-in server, but failed when I tried to run it through Gunicorn. For some reason, this kind of circular import just doesn’t work with it! I am still trying to figure out why, but meanwhile, the fix was to reference ForeigKey with a string. Now I don’t have the offending import in comments/models.py and I reference the foreign key like this:
class Comment(MPTTModel, TimeStampedModel):
...
article = models.ForeignKey("news.Article", related_name='comments')