I have a Django project. A part from this Django project was a reporting module that searches for reports directory inside all INSTALLED_APPS, very similar to autodiscover mechanism of the admin interface.
This module had a small registery class that registers classes found. In a very simplified way it looks something like this:
def autodiscover():
"""
Searches for reports module in all INSTALLED_APPS
"""
global REPORTSLOADING
if REPORTSLOADING:
return
REPORTSLOADING = True
import imp
from django.conf import settings
for app in settings.INSTALLED_APPS:
try:
app_path = import_module(app).__path__
except AttributeError:
continue
try:
imp.find_module('reports', app_path)
except ImportError:
continue
import_module("%s.reports" % app)
REPORTSLOADING = False
class ReportsRegistery(object):
.....
registery = ReportsRegistery()
If any of the INSTALLED_APPS need to register a Report class, we need a line inside reports/__init__.py:
import reports
reports.registery.register(SomeReportClass)
And inside the main urls.py i would do:
import reports
reports.autodiscover()
urlpatterns = patterns('',
....
(r'', include(reports.registery.urls)),
)
Now I decided to create a pluggable django application for it and placed the same code in __init__.py of the package. The problem I am facing is that reports module with the new structure gets imported twice, thus causing the recreation of the ‘registery’ object. So, no urls are actually registered. It’s loaded one time from the import inside urls.py (as expected) and another one initiated by autodiscover. I have verified this by:
print hex(id(registery))
and found out it returned 2 different values.
I thought that the reports package will be imported once just like when it was just a module.
How can I prevent it from being loaded twice ? Or how can I ensure that we will have only one ReportsRegistery instance to work with ?
It’s not uncommon for Django to import modules twice. There are two reasons for this:
The classic Django project layout encouraged you to have your working directory on the path twice at two different locations. This meant you could import something as
project.module, or asapp.project.module, which would confuse the import machinery.The settings.py file is actually imported twice.
Fixes:
Double-check that all of your imports use the same style of path.
Don’t import your module from settings.py