diff --git a/django/contrib/admin/__init__.py b/django/contrib/admin/__init__.py index abc5f09b56..92f23a90e6 100644 --- a/django/contrib/admin/__init__.py +++ b/django/contrib/admin/__init__.py @@ -4,9 +4,6 @@ from django.contrib.admin.options import StackedInline, TabularInline from django.contrib.admin.sites import AdminSite, site from django.utils.importlib import import_module -# A flag to tell us if autodiscover is running. autodiscover will set this to -# True while running, and False when it finishes. -LOADING = False def autodiscover(): """ @@ -14,16 +11,8 @@ def autodiscover(): not present. This forces an import on them to register any admin bits they may want. """ - # Bail out if autodiscover didn't finish loading from a previous call so - # that we avoid running autodiscover again when the URLconf is loaded by - # the exception handler to resolve the handler500 view. This prevents an - # admin.py module with errors from re-registering models and raising a - # spurious AlreadyRegistered exception (see #8245). - global LOADING - if LOADING: - return - LOADING = True + import copy import imp from django.conf import settings @@ -54,6 +43,13 @@ def autodiscover(): # Step 3: import the app's admin file. If this has errors we want them # to bubble up. - import_module("%s.admin" % app) - # autodiscover was successful, reset loading flag. - LOADING = False + try: + before_import_registry = copy.copy(site._registry) + import_module('%s.admin' % app) + except: + # Reset the model registry to the state before the last import as + # this import will have to reoccur on the next request and this + # could raise NotRegistered and AlreadyRegistered exceptions + # (see #8245). + site._registry = before_import_registry + raise diff --git a/tests/regressiontests/bug8245/tests.py b/tests/regressiontests/bug8245/tests.py index c1cc3b595c..b7c7bcdf7c 100644 --- a/tests/regressiontests/bug8245/tests.py +++ b/tests/regressiontests/bug8245/tests.py @@ -18,6 +18,13 @@ class Bug8245Test(TestCase): else: self.fail( 'autodiscover should have raised a "Bad admin module" error.') - # Calling autodiscover again should bail out early and not raise an - # AlreadyRegistered error. - admin.autodiscover() + + # Calling autodiscover again should raise the very same error it did + # the first time, not an AlreadyRegistered error. + try: + admin.autodiscover() + except Exception, e: + self.failUnlessEqual(str(e), "Bad admin module") + else: + self.fail( + 'autodiscover should have raised a "Bad admin module" error.')