Browse files

Merge pull request #114 from ixc/master

Fixed custom User compatibility in Django 1.5, preventing circular imports.
  • Loading branch information...
2 parents 03375a4 + 0351641 commit b7751180238c2ad2a9f0686c404654365481cdfe @lukaszb lukaszb committed Feb 15, 2013
View
1 AUTHORS
@@ -14,3 +14,4 @@ Authors ordered by first contribution
- Rach Belaid <rachid.belaid@gmail.com>
- Michael Crosby <crosby.michael@gmail.com>
- Greg Hinch <greg@greghinch.com>
+- Aram Dulyan <aram@dulyan.com>
View
10 guardian/admin.py
@@ -10,13 +10,15 @@
from django.utils.datastructures import SortedDict
from django.utils.translation import ugettext, ugettext_lazy as _
+from guardian.compat import get_user_model
from guardian.forms import UserObjectPermissionsForm
from guardian.forms import GroupObjectPermissionsForm
from guardian.shortcuts import get_perms
from guardian.shortcuts import get_users_with_perms
from guardian.shortcuts import get_groups_with_perms
from guardian.shortcuts import get_perms_for_model
-from guardian.models import User, Group
+from guardian.models import Group
+
class AdminUserObjectPermissionsForm(UserObjectPermissionsForm):
"""
@@ -240,7 +242,7 @@ def obj_perms_manage_user_view(self, request, object_pk, user_id):
"""
Manages selected users' permissions for current object.
"""
- user = get_object_or_404(User, id=user_id)
+ user = get_object_or_404(get_user_model(), id=user_id)
obj = get_object_or_404(self.queryset(request), pk=object_pk)
form_class = self.get_obj_perms_manage_user_form()
form = form_class(user, obj, request.POST or None)
@@ -357,9 +359,9 @@ def clean_user(self):
"""
username = self.cleaned_data['user']
try:
- user = User.objects.get(username=username)
+ user = get_user_model().objects.get(username=username)
return user
- except User.DoesNotExist:
+ except get_user_model().DoesNotExist:
raise forms.ValidationError(
self.fields['user'].error_messages['does_not_exist'])
View
4 guardian/backends.py
@@ -1,9 +1,9 @@
from django.db import models
+from guardian.compat import get_user_model
from guardian.conf import settings
from guardian.exceptions import WrongAppError
from guardian.core import ObjectPermissionChecker
-from guardian.models import User
class ObjectPermissionBackend(object):
supports_object_permissions = True
@@ -43,7 +43,7 @@ def has_perm(self, user_obj, perm, obj=None):
# This is how we support anonymous users - simply try to retrieve User
# instance and perform checks for that predefined user
if not user_obj.is_authenticated():
- user_obj = User.objects.get(pk=settings.ANONYMOUS_USER_ID)
+ user_obj = get_user_model().objects.get(pk=settings.ANONYMOUS_USER_ID)
# Do not check any further if user is not active
if not user_obj.is_active:
View
18 guardian/compat.py
@@ -1,4 +1,5 @@
import django
+from django.conf import settings
from django.contrib.auth.models import Group
from django.contrib.auth.models import Permission
from django.contrib.auth.models import AnonymousUser
@@ -13,17 +14,24 @@
'Group',
'Permission',
'AnonymousUser',
+ 'get_user_model',
+ 'user_model_label',
'url',
'patterns',
'include',
'handler404',
'handler500'
]
-# Django 1.5+ compatibility
-if django.VERSION >= (1, 5):
+# Django 1.5 compatibility utilities, providing support for custom User models.
+# Since get_user_model() causes a circular import if called when app models are
+# being loaded, the user_model_label should be used when possible, with calls
+# to get_user_model deferred to execution time
+
+user_model_label = getattr(settings, 'AUTH_USER_MODEL', 'auth.User')
+
+try:
from django.contrib.auth import get_user_model
- User = get_user_model()
-else:
+except ImportError:
from django.contrib.auth.models import User
-
+ get_user_model = lambda: User
View
2 guardian/forms.py
@@ -106,7 +106,7 @@ class UserObjectPermissionsForm(BaseObjectPermissionsForm):
from django.shortcuts import get_object_or_404
from myapp.models import Post
from guardian.forms import UserObjectPermissionsForm
- from guardian.models import User
+ from django.contrib.auth.models import User
def my_view(request, post_slug, user_id):
user = get_object_or_404(User, id=user_id)
View
3 guardian/management/__init__.py
@@ -3,12 +3,13 @@
from guardian import models as guardian_app
from guardian.conf import settings as guardian_settings
-from guardian.models import User
+from guardian.compat import get_user_model
def create_anonymous_user(sender, **kwargs):
"""
Creates anonymous User instance with id from settings.
"""
+ User = get_user_model()
try:
User.objects.get(pk=guardian_settings.ANONYMOUS_USER_ID)
except User.DoesNotExist:
View
10 guardian/models.py
@@ -8,7 +8,8 @@
from guardian.compat import AnonymousUser
from guardian.compat import Group
from guardian.compat import Permission
-from guardian.compat import User
+from guardian.compat import get_user_model
+from guardian.compat import user_model_label
from guardian.managers import GroupObjectPermissionManager
from guardian.managers import UserObjectPermissionManager
from guardian.utils import get_anonymous_user
@@ -51,7 +52,7 @@ class UserObjectPermission(BaseObjectPermission):
"""
**Manager**: :manager:`UserObjectPermissionManager`
"""
- user = models.ForeignKey(User)
+ user = models.ForeignKey(user_model_label)
objects = UserObjectPermissionManager()
@@ -71,13 +72,16 @@ class Meta:
unique_together = ['group', 'permission', 'content_type', 'object_pk']
+# At this point, it's safe to call get_user_model without risking a circular
+# import, since all the models have been parsed
+User = get_user_model()
# Prototype User and Group methods
setattr(User, 'get_anonymous', staticmethod(lambda: get_anonymous_user()))
setattr(User, 'add_obj_perm',
lambda self, perm, obj: UserObjectPermission.objects.assign(perm, self, obj))
setattr(User, 'del_obj_perm',
lambda self, perm, obj: UserObjectPermission.objects.remove_perm(perm, self, obj))
-
+
setattr(Group, 'add_obj_perm',
lambda self, perm, obj: GroupObjectPermission.objects.assign(perm, self, obj))
setattr(Group, 'del_obj_perm',
View
7 guardian/shortcuts.py
@@ -8,12 +8,13 @@
from django.shortcuts import _get_queryset
from itertools import groupby
+from guardian.compat import get_user_model
from guardian.core import ObjectPermissionChecker
from guardian.exceptions import MixedContentTypeError
from guardian.exceptions import WrongAppError
from guardian.models import UserObjectPermission, GroupObjectPermission
from guardian.utils import get_identity
-from guardian.models import Permission, User, Group
+from guardian.models import Permission, Group
def assign(perm, user_or_group, obj=None):
"""
@@ -164,7 +165,7 @@ def get_users_with_perms(obj, attach_perms=False, with_superusers=False,
Example::
>>> from django.contrib.flatpages.models import FlatPage
- >>> from guardian.models import User
+ >>> from django.contrib.auth.models import User
>>> from guardian.shortcuts import assign, get_users_with_perms
>>>
>>> page = FlatPage.objects.create(title='Some page', path='/some/page/')
@@ -192,7 +193,7 @@ def get_users_with_perms(obj, attach_perms=False, with_superusers=False,
)
if with_superusers:
qset = qset | Q(is_superuser=True)
- return User.objects.filter(qset).distinct()
+ return get_user_model().objects.filter(qset).distinct()
else:
# TODO: Do not hit db for each user!
users = {}
View
7 guardian/templatetags/guardian_tags.py
@@ -10,9 +10,10 @@
from django.template import InvalidTemplateLibrary
from django.template.defaulttags import LoadNode
+from guardian.compat import get_user_model
from guardian.exceptions import NotUserNorGroup
from guardian.core import ObjectPermissionChecker
-from guardian.models import User, Group, AnonymousUser
+from guardian.models import Group, AnonymousUser
register = template.Library()
@@ -60,11 +61,11 @@ def __init__(self, for_whom, obj, context_var):
def render(self, context):
for_whom = self.for_whom.resolve(context)
- if isinstance(for_whom, User):
+ if isinstance(for_whom, get_user_model()):
self.user = for_whom
self.group = None
elif isinstance(for_whom, AnonymousUser):
- self.user = User.get_anonymous()
+ self.user = get_user_model().get_anonymous()
self.group = None
elif isinstance(for_whom, Group):
self.user = None
View
9 guardian/tests/admin_test.py
@@ -11,15 +11,22 @@
from django.test.client import Client
from guardian.admin import GuardedModelAdmin
+from guardian.compat import get_user_model
from guardian.shortcuts import get_perms
from guardian.shortcuts import get_perms_for_model
from guardian.tests.conf import TEST_SETTINGS
from guardian.tests.conf import override_settings
-from guardian.models import User, Group
+from guardian.models import Group
+
+User = get_user_model()
class ContentTypeGuardedAdmin(GuardedModelAdmin):
pass
+try:
+ admin.site.unregister(ContentType)
+except admin.sites.NotRegistered:
+ pass
admin.site.register(ContentType, ContentTypeGuardedAdmin)
@override_settings(**TEST_SETTINGS)
View
5 guardian/tests/core_test.py
@@ -7,10 +7,13 @@
from django.test import TestCase
from guardian.core import ObjectPermissionChecker
+from guardian.compat import get_user_model
from guardian.exceptions import NotUserNorGroup
from guardian.models import UserObjectPermission, GroupObjectPermission
from guardian.shortcuts import assign
-from guardian.models import User, Group, Permission, AnonymousUser
+from guardian.models import Group, Permission, AnonymousUser
+
+User = get_user_model()
class ObjectPermissionTestCase(TestCase):
View
7 guardian/tests/custompkmodel_test.py
@@ -1,8 +1,9 @@
-
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase
+
+from guardian.compat import get_user_model
from guardian.shortcuts import assign, remove_perm
-from guardian.models import User
+
class CustomPKModelTest(TestCase):
"""
@@ -11,7 +12,7 @@ class CustomPKModelTest(TestCase):
"""
def setUp(self):
- self.user = User.objects.create(username='joe')
+ self.user = get_user_model().objects.create(username='joe')
self.ctype = ContentType.objects.create(name='foo', model='bar',
app_label='fake-for-guardian-tests')
View
7 guardian/tests/decorators_test.py
@@ -1,21 +1,24 @@
import mock
from django.conf import settings
from django.core.exceptions import PermissionDenied
+from django.db.models.base import ModelBase
from django.http import HttpRequest
from django.http import HttpResponse
from django.http import HttpResponseForbidden
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.template import TemplateDoesNotExist
from django.test import TestCase
+
+from guardian.compat import get_user_model
from guardian.decorators import permission_required, permission_required_or_403
from guardian.exceptions import GuardianError
from guardian.shortcuts import assign
from guardian.tests.conf import TEST_SETTINGS
from guardian.tests.conf import override_settings
-from guardian.models import User, Group, AnonymousUser
-from django.db.models.base import ModelBase
+from guardian.models import Group, AnonymousUser
+User = get_user_model()
@override_settings(**TEST_SETTINGS)
class PermissionRequiredTest(TestCase):
View
5 guardian/tests/forms_test.py
@@ -1,13 +1,14 @@
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase
+from guardian.compat import get_user_model
from guardian.forms import BaseObjectPermissionsForm
-from guardian.models import User
class BaseObjectPermissionsFormTests(TestCase):
def setUp(self):
- self.user = User.objects.create_user('joe', 'joe@example.com', 'joe')
+ self.user = get_user_model().objects.create_user(
+ 'joe', 'joe@example.com', 'joe')
self.obj = ContentType.objects.create(name='foo', model='bar',
app_label='fake-for-guardian-tests')
View
6 guardian/tests/mixins_test.py
@@ -8,9 +8,10 @@
from django.views.generic import View
from mock import Mock
+from guardian.compat import get_user_model
from guardian.mixins import LoginRequiredMixin
from guardian.mixins import PermissionRequiredMixin
-from guardian.models import User, AnonymousUser
+from guardian.models import AnonymousUser
class DatabaseRemovedError(Exception):
pass
@@ -33,7 +34,8 @@ def setUp(self):
self.ctype = ContentType.objects.create(name='foo', model='bar',
app_label='fake-for-guardian-tests')
self.factory = RequestFactory()
- self.user = User.objects.create_user('joe', 'joe@doe.com', 'doe')
+ self.user = get_user_model().objects.create_user(
+ 'joe', 'joe@doe.com', 'doe')
self.client.login(username='joe', password='doe')
def test_permission_is_checked_before_view_is_computed(self):
View
7 guardian/tests/orphans_test.py
@@ -4,15 +4,16 @@
from django.core.management import call_command
from django.test import TestCase
+from guardian.compat import get_user_model
from guardian.utils import clean_orphan_obj_perms
from guardian.shortcuts import assign
-from guardian.models import User, Group
+from guardian.models import Group
class OrphanedObjectPermissionsTest(TestCase):
def setUp(self):
# Create objects for which we would assing obj perms
- self.target_user1 = User.objects.create(username='user1')
+ self.target_user1 = get_user_model().objects.create(username='user1')
self.target_group1 = Group.objects.create(name='group1')
self.target_obj1 = ContentType.objects.create(name='ct1', model='foo',
app_label='fake-for-guardian-tests')
@@ -22,7 +23,7 @@ def setUp(self):
create_permissions(auth_app, [], 1)
- self.user = User.objects.create(username='user')
+ self.user = get_user_model().objects.create(username='user')
self.group = Group.objects.create(name='group')
def test_clean_perms(self):
View
4 guardian/tests/other_test.py
@@ -6,6 +6,7 @@
import guardian
from guardian.backends import ObjectPermissionBackend
+from guardian.compat import get_user_model
from guardian.exceptions import GuardianError
from guardian.exceptions import NotUserNorGroup
from guardian.exceptions import ObjectNotPersisted
@@ -15,7 +16,8 @@
from guardian.models import AnonymousUser
from guardian.models import Group
from guardian.models import Permission
-from guardian.models import User
+
+User = get_user_model()
class UserPermissionTests(TestCase):
View
5 guardian/tests/shortcuts_test.py
@@ -5,6 +5,7 @@
from guardian.shortcuts import get_perms_for_model
from guardian.core import ObjectPermissionChecker
+from guardian.compat import get_user_model
from guardian.shortcuts import assign
from guardian.shortcuts import remove_perm
from guardian.shortcuts import get_perms
@@ -16,7 +17,9 @@
from guardian.exceptions import NotUserNorGroup
from guardian.exceptions import WrongAppError
from guardian.tests.core_test import ObjectPermissionTestCase
-from guardian.models import User, Group, Permission
+from guardian.models import Group, Permission
+
+User = get_user_model()
class ShortcutsTests(ObjectPermissionTestCase):
View
5 guardian/tests/tags_test.py
@@ -3,9 +3,12 @@
from django.template import Template, Context, TemplateSyntaxError
from django.contrib.contenttypes.models import ContentType
+from guardian.compat import get_user_model
from guardian.exceptions import NotUserNorGroup
from guardian.models import UserObjectPermission, GroupObjectPermission
-from guardian.models import User, Group, AnonymousUser
+from guardian.models import Group, AnonymousUser
+
+User = get_user_model()
def render(template, context):
"""
View
5 guardian/tests/utils_test.py
@@ -1,10 +1,13 @@
from django.test import TestCase
+from guardian.compat import get_user_model
from guardian.tests.core_test import ObjectPermissionTestCase
from guardian.utils import get_anonymous_user, get_identity
from guardian.exceptions import NotUserNorGroup
-from guardian.models import User, Group, AnonymousUser
+from guardian.models import Group, AnonymousUser
+
+User = get_user_model()
class GetAnonymousUserTest(TestCase):
View
6 guardian/utils.py
@@ -18,7 +18,7 @@
from guardian.compat import AnonymousUser
from guardian.compat import Group
-from guardian.compat import User
+from guardian.compat import get_user_model
from guardian.conf import settings as guardian_settings
from guardian.exceptions import NotUserNorGroup
@@ -31,7 +31,7 @@ def get_anonymous_user():
Returns ``User`` instance (not ``AnonymousUser``) depending on
``ANONYMOUS_USER_ID`` configuration.
"""
- return User.objects.get(id=guardian_settings.ANONYMOUS_USER_ID)
+ return get_user_model().objects.get(id=guardian_settings.ANONYMOUS_USER_ID)
def get_identity(identity):
@@ -67,7 +67,7 @@ def get_identity(identity):
if isinstance(identity, AnonymousUser):
identity = get_anonymous_user()
- if isinstance(identity, User):
+ if isinstance(identity, get_user_model()):
return identity, None
elif isinstance(identity, Group):
return None, identity

0 comments on commit b775118

Please sign in to comment.