diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py
index 426bd69..3f56386 100644
--- a/django/contrib/auth/__init__.py
+++ b/django/contrib/auth/__init__.py
@@ -177,8 +177,9 @@ def logout(request):
         request.session[LANGUAGE_SESSION_KEY] = language
 
     if hasattr(request, 'user'):
-        from django.contrib.auth.models import AnonymousUser
-        request.user = AnonymousUser()
+        # from django.contrib.auth.models import AnonymousUser
+        # request.user = AnonymousUser()
+        request.user = get_user_model().get_anonymous_user()
 
 
 def get_user_model():
@@ -200,7 +201,7 @@ def get_user(request):
     Returns the user model instance associated with the given request session.
     If no user is retrieved an instance of `AnonymousUser` is returned.
     """
-    from .models import AnonymousUser
+    # from .models import AnonymousUser
     user = None
     try:
         user_id = _get_user_session_key(request)
@@ -222,7 +223,8 @@ def get_user(request):
                     request.session.flush()
                     user = None
 
-    return user or AnonymousUser()
+    # return user or AnonymousUser()
+    return user or get_user_model().get_anonymous_user()
 
 
 def get_permission_codename(action, opts):
diff --git a/django/contrib/auth/backends.py b/django/contrib/auth/backends.py
index 8df95db..f089783 100644
--- a/django/contrib/auth/backends.py
+++ b/django/contrib/auth/backends.py
@@ -1,7 +1,6 @@
 from __future__ import unicode_literals
 
 from django.contrib.auth import get_user_model
-from django.contrib.auth.models import Permission
 
 UserModel = get_user_model()
 
@@ -36,6 +35,7 @@ class ModelBackend(object):
         return user_obj.user_permissions.all()
 
     def _get_group_permissions(self, user_obj):
+        from django.contrib.auth.models import Permission
         user_groups_field = get_user_model()._meta.get_field('groups')
         user_groups_query = 'group__%s' % user_groups_field.related_query_name()
         return Permission.objects.filter(**{user_groups_query: user_obj})
@@ -49,6 +49,7 @@ class ModelBackend(object):
         if not user_obj.is_active or user_obj.is_anonymous or obj is not None:
             return set()
 
+        from django.contrib.auth.models import Permission
         perm_cache_name = '_%s_perm_cache' % from_name
         if not hasattr(user_obj, perm_cache_name):
             if user_obj.is_superuser:
diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py
index 6055526..254fc42 100644
--- a/django/contrib/auth/models.py
+++ b/django/contrib/auth/models.py
@@ -296,6 +296,82 @@ class PermissionsMixin(models.Model):
         return _user_has_module_perms(self, app_label)
 
 
+@python_2_unicode_compatible
+class AnonymousUser(object):
+    id = None
+    pk = None
+    username = ''
+    is_staff = False
+    is_active = False
+    is_superuser = False
+    _groups = EmptyManager(Group)
+    _user_permissions = EmptyManager(Permission)
+
+    def __init__(self):
+        pass
+
+    def __str__(self):
+        return 'AnonymousUser'
+
+    def __eq__(self, other):
+        return isinstance(other, self.__class__)
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def __hash__(self):
+        return 1  # instances always return the same hash value
+
+    def save(self):
+        raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")
+
+    def delete(self):
+        raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")
+
+    def set_password(self, raw_password):
+        raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")
+
+    def check_password(self, raw_password):
+        raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")
+
+    @property
+    def groups(self):
+        return self._groups
+
+    @property
+    def user_permissions(self):
+        return self._user_permissions
+
+    def get_group_permissions(self, obj=None):
+        return set()
+
+    def get_all_permissions(self, obj=None):
+        return _user_get_all_permissions(self, obj=obj)
+
+    def has_perm(self, perm, obj=None):
+        return _user_has_perm(self, perm, obj=obj)
+
+    def has_perms(self, perm_list, obj=None):
+        for perm in perm_list:
+            if not self.has_perm(perm, obj):
+                return False
+        return True
+
+    def has_module_perms(self, module):
+        return _user_has_module_perms(self, module)
+
+    @property
+    def is_anonymous(self):
+        return CallableTrue
+
+    @property
+    def is_authenticated(self):
+        return CallableFalse
+
+    def get_username(self):
+        return self.username
+
+
 class AbstractUser(AbstractBaseUser, PermissionsMixin):
     """
     An abstract base class implementing a fully featured User model with
@@ -365,6 +441,15 @@ class AbstractUser(AbstractBaseUser, PermissionsMixin):
         """
         send_mail(subject, message, from_email, [self.email], **kwargs)
 
+    @classmethod
+    def get_anonymous_user(cls):
+        """Return an instance of AnonymousUser. Alternative implementations
+        for AUTH_USER_MODEL may override this to use an alternative
+        AnonymousUser class or add custom initialization.
+
+        """
+        return AnonymousUser()
+
 
 class User(AbstractUser):
     """
@@ -373,81 +458,9 @@ class User(AbstractUser):
 
     Username, password and email are required. Other fields are optional.
     """
+
     class Meta(AbstractUser.Meta):
         swappable = 'AUTH_USER_MODEL'
 
 
-@python_2_unicode_compatible
-class AnonymousUser(object):
-    id = None
-    pk = None
-    username = ''
-    is_staff = False
-    is_active = False
-    is_superuser = False
-    _groups = EmptyManager(Group)
-    _user_permissions = EmptyManager(Permission)
-
-    def __init__(self):
-        pass
-
-    def __str__(self):
-        return 'AnonymousUser'
-
-    def __eq__(self, other):
-        return isinstance(other, self.__class__)
-
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def __hash__(self):
-        return 1  # instances always return the same hash value
-
-    def save(self):
-        raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")
-
-    def delete(self):
-        raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")
-
-    def set_password(self, raw_password):
-        raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")
-
-    def check_password(self, raw_password):
-        raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")
-
-    @property
-    def groups(self):
-        return self._groups
-
-    @property
-    def user_permissions(self):
-        return self._user_permissions
-
-    def get_group_permissions(self, obj=None):
-        return set()
-
-    def get_all_permissions(self, obj=None):
-        return _user_get_all_permissions(self, obj=obj)
-
-    def has_perm(self, perm, obj=None):
-        return _user_has_perm(self, perm, obj=obj)
-
-    def has_perms(self, perm_list, obj=None):
-        for perm in perm_list:
-            if not self.has_perm(perm, obj):
-                return False
-        return True
-
-    def has_module_perms(self, module):
-        return _user_has_module_perms(self, module)
-
-    @property
-    def is_anonymous(self):
-        return CallableTrue
-
-    @property
-    def is_authenticated(self):
-        return CallableFalse
-
-    def get_username(self):
-        return self.username
+    
