Skip to content

Commit 76ccdff

Browse files
committed
Role profiles using multi-table inheritance.
1 parent 986d32b commit 76ccdff

File tree

5 files changed

+56
-63
lines changed

5 files changed

+56
-63
lines changed

testproject/urls.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from django.conf.urls import patterns, include, url
22

3+
34
# Uncomment the next two lines to enable the admin:
45
# from django.contrib import admin
56
# admin.autodiscover()

userroles/__init__.py

-9
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,6 @@ def roles_dict(self):
4343
if isinstance(item, basestring):
4444
# An item like 'manager'
4545
self._roles_dict[item] = None
46-
elif len(item) == 2:
47-
# An item like ('manager', 'myapp.models.ManagerProfile')
48-
# or ('manager', '')
49-
name, profile = item
50-
try:
51-
profile_class = _import_class_from_string(profile)
52-
except:
53-
raise ImproperlyConfigured(_IMPORT_FAILED, profile)
54-
self._roles_dict[name] = profile_class
5546
else:
5647
# Anything else
5748
raise ImproperlyConfigured(_INCORRECT_ARGS)

userroles/models.py

+25-25
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,52 @@
11
from django.contrib.auth.models import User
2-
from django.contrib.contenttypes.models import ContentType
3-
from django.contrib.contenttypes import generic
42
from django.db import models
53
from userroles import roles
64

75

86
class UserRole(models.Model):
97
user = models.OneToOneField(User, related_name='role')
108
name = models.CharField(max_length=100, choices=roles.choices)
11-
content_type = models.ForeignKey(ContentType, null=True, blank=True)
12-
object_id = models.PositiveIntegerField(null=True, blank=True)
13-
profile = generic.GenericForeignKey('content_type', 'object_id')
14-
valid_roles = roles
9+
child = models.CharField(max_length=100, blank=True)
10+
_valid_roles = roles
11+
12+
@property
13+
def profile(self):
14+
if not self.child:
15+
return None
16+
return getattr(self, self.child)
1517

1618
def __eq__(self, other):
1719
return self.name == other.name
1820

1921
def __getattr__(self, name):
2022
if name.startswith('is_'):
21-
role = getattr(self.valid_roles, name[3:], None)
23+
role = getattr(self._valid_roles, name[3:], None)
2224
if role:
2325
return self == role
2426

2527
raise AttributeError("'%s' object has no attribute '%s'" %
26-
(self.__class__.__name__, name))
28+
(self.__class__.__name__, name))
2729

2830
def __unicode__(self):
2931
return self.name
3032

3133

3234
def set_user_role(user, role, profile=None):
33-
profile_class = UserRole.valid_roles.roles_dict[role.name]
34-
35-
if profile_class and not profile:
36-
raise ValueError("You must set a profile for '%s' role" % role.name)
37-
elif profile and not profile_class:
38-
raise ValueError("Cannot set a profile for '%s' role" % role.name)
39-
elif profile and not isinstance(profile, profile_class):
40-
raise ValueError("Incorrect profile for '%s' role" % role.name)
41-
4235
if profile:
43-
profile.save()
36+
try:
37+
UserRole.objects.get(user=user).delete()
38+
except UserRole.DoesNotExist:
39+
pass
40+
profile.user = user
41+
profile.name = role.name
42+
profile.child = str(profile.__class__.__name__).lower()
4443

45-
try:
46-
role_obj = UserRole.objects.get(user=user)
47-
except UserRole.DoesNotExist:
48-
role_obj = UserRole(user=user, name=role.name)
4944
else:
50-
role_obj.name = role.name
51-
role_obj.profile = profile
52-
role_obj.save()
45+
try:
46+
profile = UserRole.objects.get(user=user)
47+
except UserRole.DoesNotExist:
48+
profile = UserRole(user=user, name=role.name)
49+
else:
50+
profile.name = role.name
51+
52+
profile.save()

userroles/testapp/models.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from django.db import models
2+
from userroles.models import UserRole
23

34

4-
class ModeratorProfile(models.Model):
5+
class TestModeratorProfile(UserRole):
56
stars = models.IntegerField()

userroles/tests.py

+28-28
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@
55
from django.contrib.auth.models import User
66
from milkman.dairy import milkman
77
from userroles.models import set_user_role, UserRole
8-
from userroles.testapp.models import ModeratorProfile
8+
from userroles.testapp.models import TestModeratorProfile
99
from userroles.utils import SettingsTestCase
1010
from userroles import Roles
1111

1212
# Test setup
1313

1414
roles_config = (
15-
('manager', ''),
16-
('moderator', 'userroles.testapp.models.ModeratorProfile'),
17-
('client', ''),
15+
'manager',
16+
'moderator',
17+
'client',
1818
)
1919

2020
installed_apps_config = list(settings.INSTALLED_APPS)
@@ -31,11 +31,11 @@ def setUp(self):
3131
ROOT_URLCONF='userroles.testapp.urls',
3232
USER_ROLES=roles_config
3333
)
34-
self.restore_roles = UserRole.valid_roles
35-
UserRole.valid_roles = roles
34+
self.restore_roles = UserRole._valid_roles
35+
UserRole._valid_roles = roles
3636

3737
def tearDown(self):
38-
UserRole.valid_roles = self.restore_roles
38+
UserRole._valid_roles = self.restore_roles
3939

4040

4141
class DummyClass(object):
@@ -113,30 +113,30 @@ def test_set_role_with_profile(self):
113113
"""
114114
Set a role that takes a profile.
115115
"""
116-
set_user_role(self.user, roles.moderator, ModeratorProfile(stars=5))
116+
set_user_role(self.user, roles.moderator, TestModeratorProfile(stars=5))
117117
self.assertTrue(self.user.role.is_moderator)
118118
self.assertEquals(self.user.role.profile.stars, 5)
119119

120-
def test_set_role_without_profile_incorrectly(self):
121-
"""
122-
Attempt to set a profile on a role that does not take a profile.
123-
"""
124-
args = (self.user, roles.client, ModeratorProfile())
125-
self.assertRaises(ValueError, set_user_role, *args)
126-
127-
def test_set_role_with_profile_incorrectly(self):
128-
"""
129-
Attempt to set a role that uses profiles, without setting a profile.
130-
"""
131-
args = (self.user, roles.moderator, )
132-
self.assertRaises(ValueError, set_user_role, *args)
133-
134-
def test_set_role_with_profile_using_wrong_profile(self):
135-
"""
136-
Attempt to set a role that uses profiles, without setting a profile.
137-
"""
138-
args = (self.user, roles.moderator, DummyClass())
139-
self.assertRaises(ValueError, set_user_role, *args)
120+
# def test_set_role_without_profile_incorrectly(self):
121+
# """
122+
# Attempt to set a profile on a role that does not take a profile.
123+
# """
124+
# args = (self.user, roles.client, ModeratorProfile())
125+
# self.assertRaises(ValueError, set_user_role, *args)
126+
127+
# def test_set_role_with_profile_incorrectly(self):
128+
# """
129+
# Attempt to set a role that uses profiles, without setting a profile.
130+
# """
131+
# args = (self.user, roles.moderator, )
132+
# self.assertRaises(ValueError, set_user_role, *args)
133+
134+
# def test_set_role_with_profile_using_wrong_profile(self):
135+
# """
136+
# Attempt to set a role that uses profiles, without setting a profile.
137+
# """
138+
# args = (self.user, roles.moderator, DummyClass())
139+
# self.assertRaises(ValueError, set_user_role, *args)
140140

141141

142142
# Tests for user role view decorators

0 commit comments

Comments
 (0)