Fixed #13914 -- Added natural keys to User and Group models in auth contrib app. Thanks, jbochi and closedbracket.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17429 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jannis Leidel 2012-02-04 12:48:01 +00:00
parent 6ecadcbdd2
commit 954e3b4ad3
6 changed files with 120 additions and 6 deletions

View File

@ -0,0 +1,32 @@
[
{
"pk": 1,
"model": "auth.group",
"fields": {
"name": "my_group",
"permissions": []
}
},
{
"pk": 1,
"model": "auth.user",
"fields": {
"username": "my_username",
"first_name": "",
"last_name": "",
"is_active": true,
"is_superuser": true,
"is_staff": true,
"last_login": "2012-01-13 00:14:00",
"groups": [
[
"my_group"
]
],
"user_permissions": [],
"password": "pbkdf2_sha256$10000$LUyhxJjuLwXF$f6Zbpnx1L5dPze8m0itBaHMDyZ/n6JyhuavQy2RrBIM=",
"email": "email@example.com",
"date_joined": "2012-01-13 00:14:00"
}
}
]

View File

@ -0,0 +1,30 @@
[
{
"pk": 1,
"model": "auth.group",
"fields": {
"name": "my_group",
"permissions": []
}
},
{
"pk": 1,
"model": "auth.user",
"fields": {
"username": "my_username",
"first_name": "",
"last_name": "",
"is_active": true,
"is_superuser": true,
"is_staff": true,
"last_login": "2012-01-13 00:14:00",
"groups": [
1
],
"user_permissions": [],
"password": "pbkdf2_sha256$10000$LUyhxJjuLwXF$f6Zbpnx1L5dPze8m0itBaHMDyZ/n6JyhuavQy2RrBIM=",
"email": "email@example.com",
"date_joined": "2012-01-13 00:14:00"
}
}
]

View File

@ -86,6 +86,13 @@ class Permission(models.Model):
natural_key.dependencies = ['contenttypes.contenttype']
class GroupManager(models.Manager):
"""
The manager for the auth's Group model.
"""
def get_by_natural_key(self, name):
return self.get(name=name)
class Group(models.Model):
"""
Groups are a generic way of categorizing users to apply permissions, or
@ -107,6 +114,8 @@ class Group(models.Model):
permissions = models.ManyToManyField(Permission,
verbose_name=_('permissions'), blank=True)
objects = GroupManager()
class Meta:
verbose_name = _('group')
verbose_name_plural = _('groups')
@ -114,6 +123,9 @@ class Group(models.Model):
def __unicode__(self):
return self.name
def natural_key(self):
return (self.name,)
class UserManager(models.Manager):
def create_user(self, username, email=None, password=None):
@ -160,6 +172,9 @@ class UserManager(models.Manager):
"""
return get_random_string(length, allowed_chars)
def get_by_natural_key(self, username):
return self.get(username=username)
# A few helper functions for common logic between User and AnonymousUser.
def _user_get_all_permissions(user, obj):
@ -240,6 +255,9 @@ class User(models.Model):
def __unicode__(self):
return self.username
def natural_key(self):
return (self.username,)
def get_absolute_url(self):
return "/users/%s/" % urllib.quote(smart_str(self.username))

View File

@ -10,12 +10,13 @@ from django.contrib.auth.tests.forms import (UserCreationFormTest,
from django.contrib.auth.tests.remote_user import (RemoteUserTest,
RemoteUserNoCreateTest, RemoteUserCustomTest)
from django.contrib.auth.tests.management import GetDefaultUsernameTestCase
from django.contrib.auth.tests.models import ProfileTestCase
from django.contrib.auth.tests.models import (ProfileTestCase, NaturalKeysTestCase,
LoadDataWithoutNaturalKeysTestCase, LoadDataWithNaturalKeysTestCase)
from django.contrib.auth.tests.hashers import TestUtilsHashPass
from django.contrib.auth.tests.signals import SignalTestCase
from django.contrib.auth.tests.tokens import TokenGeneratorTest
from django.contrib.auth.tests.views import (AuthViewNamedURLTests,
PasswordResetTest, ChangePasswordTest, LoginTest, LogoutTest,
from django.contrib.auth.tests.views import (AuthViewNamedURLTests,
PasswordResetTest, ChangePasswordTest, LoginTest, LogoutTest,
LoginURLSettings)
# The password for the fixture data users is 'password'

View File

@ -1,6 +1,6 @@
from django.conf import settings
from django.test import TestCase
from django.contrib.auth.models import User, SiteProfileNotAvailable
from django.contrib.auth.models import Group, User, SiteProfileNotAvailable
class ProfileTestCase(TestCase):
fixtures = ['authtestdata.json']
@ -26,10 +26,41 @@ class ProfileTestCase(TestCase):
user = User.objects.get(username='testclient')
self.assertRaises(SiteProfileNotAvailable, user.get_profile)
# Bad syntax in AUTH_PROFILE_MODULE:
# Bad syntax in AUTH_PROFILE_MODULE:
settings.AUTH_PROFILE_MODULE = 'foobar'
self.assertRaises(SiteProfileNotAvailable, user.get_profile)
# module that doesn't exist
settings.AUTH_PROFILE_MODULE = 'foo.bar'
self.assertRaises(SiteProfileNotAvailable, user.get_profile)
class NaturalKeysTestCase(TestCase):
fixtures = ['authtestdata.json']
def test_user_natural_key(self):
staff_user = User.objects.get(username='staff')
self.assertEquals(User.objects.get_by_natural_key('staff'), staff_user)
self.assertEquals(staff_user.natural_key(), ('staff',))
def test_group_natural_key(self):
users_group = Group.objects.create(name='users')
self.assertEquals(Group.objects.get_by_natural_key('users'), users_group)
class LoadDataWithoutNaturalKeysTestCase(TestCase):
fixtures = ['regular.json']
def test_user_is_created_and_added_to_group(self):
user = User.objects.get(username='my_username')
group = Group.objects.get(name='my_group')
self.assertEquals(group, user.groups.get())
class LoadDataWithNaturalKeysTestCase(TestCase):
fixtures = ['natural.json']
def test_user_is_created_and_added_to_group(self):
user = User.objects.get(username='my_username')
group = Group.objects.get(name='my_group')
self.assertEquals(group, user.groups.get())

View File

@ -215,7 +215,9 @@ automatically created by Django during the database synchronization process,
the primary key of a given content type isn't easy to predict; it will
depend on how and when :djadmin:`syncdb` was executed. This is true for all
models which automatically generate objects, notably including
:class:`~django.contrib.auth.models.Permission`.
:class:`~django.contrib.auth.models.Permission`,
:class:`~django.contrib.auth.models.Group`, and
:class:`~django.contrib.auth.models.User`.
.. warning::