djm_ committed fb3d291

Including Django 1.5's get_user_model at the module level causes the code to be run at initialisation time (if calling code from the models file, say to subclass); this can cause circular import issues when using a custom user model. The solution and what this commit fixes is to 1) lazy link Foreign Key fields by using strings instead of actual imports - this is recommended in the Django documentation & more importantly 2) to replace calls to User with run-time imports as opposed to init time imports.

Comments (0)

Files changed (2)


+from django.conf import settings
+__all__ = ['get_user_model', 'AUTH_USER_MODEL']
+def get_user_model():
+    """ Returns the appropriate User model class. As of Django 1.5, the use
+    of custom user models was allowed by changing a setting. This method
+    will no longer be required when Django 1.4 support is dropped.
+    """
+    try:
+        # Django 1.5+
+        from django.contrib.auth import get_user_model
+        model = get_user_model()
+    except IOError:
+        # Django <= 1.4
+        from django.contrib.auth.models import User
+        model = User
+    return model
+# The Django docs recommend referencing all user FK's by string
+# to avoid the issues caused by having initialization logic that
+# depends on the pluggable user model (which may not have been read
+# yet. This allows us to do so while keeping the extra code out of the way.
+AUTH_USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', 'auth.User')


 import re
 from django.conf import settings
-from django.contrib.auth.models import User
 from django.db import models
 from django.db import transaction
 from django.template.loader import render_to_string
 from django.utils.translation import ugettext_lazy as _
-    from django.contrib.auth import get_user_model
-    User = get_user_model()
-except ImportError:
-    from django.contrib.auth.models import User
+from registration.compat import AUTH_USER_MODEL, get_user_model
     from django.utils.timezone import now as datetime_now
         user. To disable this, pass ``send_email=False``.
-        new_user = User.objects.create_user(username, email, password)
+        new_user = get_user_model().objects.create_user(username, email, password)
         new_user.is_active = False
                     if not user.is_active:
-            except User.DoesNotExist:
+            except get_user_model().DoesNotExist:
 class RegistrationProfile(models.Model):
-    user = models.ForeignKey(User, unique=True, verbose_name=_('user'))
+    user = models.ForeignKey(AUTH_USER_MODEL, unique=True, verbose_name=_('user'))
     activation_key = models.CharField(_('activation key'), max_length=40)
     objects = RegistrationManager()