Fixed #19412 -- Added PermissionsMixin to the auth.User heirarchy.
This makes it easier to make a ModelBackend-compliant (with regards to permissions) User model. Thanks to cdestigter for the report about the relationship between ModelBackend and permissions, and to the many users on django-dev that contributed to the discussion about mixins.
This commit is contained in:
parent
bd414aed01
commit
47e1df896b
|
@ -195,38 +195,6 @@ class UserManager(BaseUserManager):
|
||||||
return u
|
return u
|
||||||
|
|
||||||
|
|
||||||
# A few helper functions for common logic between User and AnonymousUser.
|
|
||||||
def _user_get_all_permissions(user, obj):
|
|
||||||
permissions = set()
|
|
||||||
for backend in auth.get_backends():
|
|
||||||
if hasattr(backend, "get_all_permissions"):
|
|
||||||
if obj is not None:
|
|
||||||
permissions.update(backend.get_all_permissions(user, obj))
|
|
||||||
else:
|
|
||||||
permissions.update(backend.get_all_permissions(user))
|
|
||||||
return permissions
|
|
||||||
|
|
||||||
|
|
||||||
def _user_has_perm(user, perm, obj):
|
|
||||||
for backend in auth.get_backends():
|
|
||||||
if hasattr(backend, "has_perm"):
|
|
||||||
if obj is not None:
|
|
||||||
if backend.has_perm(user, perm, obj):
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
if backend.has_perm(user, perm):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def _user_has_module_perms(user, app_label):
|
|
||||||
for backend in auth.get_backends():
|
|
||||||
if hasattr(backend, "has_module_perms"):
|
|
||||||
if backend.has_module_perms(user, app_label):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class AbstractBaseUser(models.Model):
|
class AbstractBaseUser(models.Model):
|
||||||
password = models.CharField(_('password'), max_length=128)
|
password = models.CharField(_('password'), max_length=128)
|
||||||
|
@ -290,32 +258,46 @@ class AbstractBaseUser(models.Model):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
class AbstractUser(AbstractBaseUser):
|
# A few helper functions for common logic between User and AnonymousUser.
|
||||||
"""
|
def _user_get_all_permissions(user, obj):
|
||||||
An abstract base class implementing a fully featured User model with
|
permissions = set()
|
||||||
admin-compliant permissions.
|
for backend in auth.get_backends():
|
||||||
|
if hasattr(backend, "get_all_permissions"):
|
||||||
|
if obj is not None:
|
||||||
|
permissions.update(backend.get_all_permissions(user, obj))
|
||||||
|
else:
|
||||||
|
permissions.update(backend.get_all_permissions(user))
|
||||||
|
return permissions
|
||||||
|
|
||||||
Username, password and email are required. Other fields are optional.
|
|
||||||
|
def _user_has_perm(user, perm, obj):
|
||||||
|
for backend in auth.get_backends():
|
||||||
|
if hasattr(backend, "has_perm"):
|
||||||
|
if obj is not None:
|
||||||
|
if backend.has_perm(user, perm, obj):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
if backend.has_perm(user, perm):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _user_has_module_perms(user, app_label):
|
||||||
|
for backend in auth.get_backends():
|
||||||
|
if hasattr(backend, "has_module_perms"):
|
||||||
|
if backend.has_module_perms(user, app_label):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class PermissionsMixin(models.Model):
|
||||||
|
"""
|
||||||
|
A mixin class that adds the fields and methods necessary to support
|
||||||
|
Django's Group and Permission model using the ModelBackend.
|
||||||
"""
|
"""
|
||||||
username = models.CharField(_('username'), max_length=30, unique=True,
|
|
||||||
help_text=_('Required. 30 characters or fewer. Letters, numbers and '
|
|
||||||
'@/./+/-/_ characters'),
|
|
||||||
validators=[
|
|
||||||
validators.RegexValidator(re.compile('^[\w.@+-]+$'), _('Enter a valid username.'), 'invalid')
|
|
||||||
])
|
|
||||||
first_name = models.CharField(_('first name'), max_length=30, blank=True)
|
|
||||||
last_name = models.CharField(_('last name'), max_length=30, blank=True)
|
|
||||||
email = models.EmailField(_('email address'), blank=True)
|
|
||||||
is_staff = models.BooleanField(_('staff status'), default=False,
|
|
||||||
help_text=_('Designates whether the user can log into this admin '
|
|
||||||
'site.'))
|
|
||||||
is_active = models.BooleanField(_('active'), default=True,
|
|
||||||
help_text=_('Designates whether this user should be treated as '
|
|
||||||
'active. Unselect this instead of deleting accounts.'))
|
|
||||||
is_superuser = models.BooleanField(_('superuser status'), default=False,
|
is_superuser = models.BooleanField(_('superuser status'), default=False,
|
||||||
help_text=_('Designates that this user has all permissions without '
|
help_text=_('Designates that this user has all permissions without '
|
||||||
'explicitly assigning them.'))
|
'explicitly assigning them.'))
|
||||||
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
|
|
||||||
groups = models.ManyToManyField(Group, verbose_name=_('groups'),
|
groups = models.ManyToManyField(Group, verbose_name=_('groups'),
|
||||||
blank=True, help_text=_('The groups this user belongs to. A user will '
|
blank=True, help_text=_('The groups this user belongs to. A user will '
|
||||||
'get all permissions granted to each of '
|
'get all permissions granted to each of '
|
||||||
|
@ -324,30 +306,9 @@ class AbstractUser(AbstractBaseUser):
|
||||||
verbose_name=_('user permissions'), blank=True,
|
verbose_name=_('user permissions'), blank=True,
|
||||||
help_text='Specific permissions for this user.')
|
help_text='Specific permissions for this user.')
|
||||||
|
|
||||||
objects = UserManager()
|
|
||||||
|
|
||||||
USERNAME_FIELD = 'username'
|
|
||||||
REQUIRED_FIELDS = ['email']
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('user')
|
|
||||||
verbose_name_plural = _('users')
|
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
def get_absolute_url(self):
|
|
||||||
return "/users/%s/" % urlquote(self.username)
|
|
||||||
|
|
||||||
def get_full_name(self):
|
|
||||||
"""
|
|
||||||
Returns the first_name plus the last_name, with a space in between.
|
|
||||||
"""
|
|
||||||
full_name = '%s %s' % (self.first_name, self.last_name)
|
|
||||||
return full_name.strip()
|
|
||||||
|
|
||||||
def get_short_name(self):
|
|
||||||
"Returns the short name for the user."
|
|
||||||
return self.first_name
|
|
||||||
|
|
||||||
def get_group_permissions(self, obj=None):
|
def get_group_permissions(self, obj=None):
|
||||||
"""
|
"""
|
||||||
Returns a list of permission strings that this user has through his/her
|
Returns a list of permission strings that this user has through his/her
|
||||||
|
@ -405,6 +366,55 @@ class AbstractUser(AbstractBaseUser):
|
||||||
|
|
||||||
return _user_has_module_perms(self, app_label)
|
return _user_has_module_perms(self, app_label)
|
||||||
|
|
||||||
|
|
||||||
|
class AbstractUser(AbstractBaseUser, PermissionsMixin):
|
||||||
|
"""
|
||||||
|
An abstract base class implementing a fully featured User model with
|
||||||
|
admin-compliant permissions.
|
||||||
|
|
||||||
|
Username, password and email are required. Other fields are optional.
|
||||||
|
"""
|
||||||
|
username = models.CharField(_('username'), max_length=30, unique=True,
|
||||||
|
help_text=_('Required. 30 characters or fewer. Letters, numbers and '
|
||||||
|
'@/./+/-/_ characters'),
|
||||||
|
validators=[
|
||||||
|
validators.RegexValidator(re.compile('^[\w.@+-]+$'), _('Enter a valid username.'), 'invalid')
|
||||||
|
])
|
||||||
|
first_name = models.CharField(_('first name'), max_length=30, blank=True)
|
||||||
|
last_name = models.CharField(_('last name'), max_length=30, blank=True)
|
||||||
|
email = models.EmailField(_('email address'), blank=True)
|
||||||
|
is_staff = models.BooleanField(_('staff status'), default=False,
|
||||||
|
help_text=_('Designates whether the user can log into this admin '
|
||||||
|
'site.'))
|
||||||
|
is_active = models.BooleanField(_('active'), default=True,
|
||||||
|
help_text=_('Designates whether this user should be treated as '
|
||||||
|
'active. Unselect this instead of deleting accounts.'))
|
||||||
|
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
|
||||||
|
|
||||||
|
objects = UserManager()
|
||||||
|
|
||||||
|
USERNAME_FIELD = 'username'
|
||||||
|
REQUIRED_FIELDS = ['email']
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _('user')
|
||||||
|
verbose_name_plural = _('users')
|
||||||
|
abstract = True
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return "/users/%s/" % urlquote(self.username)
|
||||||
|
|
||||||
|
def get_full_name(self):
|
||||||
|
"""
|
||||||
|
Returns the first_name plus the last_name, with a space in between.
|
||||||
|
"""
|
||||||
|
full_name = '%s %s' % (self.first_name, self.last_name)
|
||||||
|
return full_name.strip()
|
||||||
|
|
||||||
|
def get_short_name(self):
|
||||||
|
"Returns the short name for the user."
|
||||||
|
return self.first_name
|
||||||
|
|
||||||
def email_user(self, subject, message, from_email=None):
|
def email_user(self, subject, message, from_email=None):
|
||||||
"""
|
"""
|
||||||
Sends an email to this User.
|
Sends an email to this User.
|
||||||
|
|
|
@ -4,7 +4,7 @@ from datetime import date
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import User, Group, Permission, AnonymousUser
|
from django.contrib.auth.models import User, Group, Permission, AnonymousUser
|
||||||
from django.contrib.auth.tests.utils import skipIfCustomUser
|
from django.contrib.auth.tests.utils import skipIfCustomUser
|
||||||
from django.contrib.auth.tests.custom_user import ExtensionUser
|
from django.contrib.auth.tests.custom_user import ExtensionUser, CustomPermissionsUser
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
|
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
|
||||||
from django.contrib.auth import authenticate
|
from django.contrib.auth import authenticate
|
||||||
|
@ -34,7 +34,7 @@ class BaseModelBackendTest(object):
|
||||||
ContentType.objects.clear_cache()
|
ContentType.objects.clear_cache()
|
||||||
|
|
||||||
def test_has_perm(self):
|
def test_has_perm(self):
|
||||||
user = self.UserModel.objects.get(username='test')
|
user = self.UserModel.objects.get(pk=self.user.pk)
|
||||||
self.assertEqual(user.has_perm('auth.test'), False)
|
self.assertEqual(user.has_perm('auth.test'), False)
|
||||||
user.is_staff = True
|
user.is_staff = True
|
||||||
user.save()
|
user.save()
|
||||||
|
@ -53,14 +53,14 @@ class BaseModelBackendTest(object):
|
||||||
self.assertEqual(user.has_perm('auth.test'), False)
|
self.assertEqual(user.has_perm('auth.test'), False)
|
||||||
|
|
||||||
def test_custom_perms(self):
|
def test_custom_perms(self):
|
||||||
user = self.UserModel.objects.get(username='test')
|
user = self.UserModel.objects.get(pk=self.user.pk)
|
||||||
content_type = ContentType.objects.get_for_model(Group)
|
content_type = ContentType.objects.get_for_model(Group)
|
||||||
perm = Permission.objects.create(name='test', content_type=content_type, codename='test')
|
perm = Permission.objects.create(name='test', content_type=content_type, codename='test')
|
||||||
user.user_permissions.add(perm)
|
user.user_permissions.add(perm)
|
||||||
user.save()
|
user.save()
|
||||||
|
|
||||||
# reloading user to purge the _perm_cache
|
# reloading user to purge the _perm_cache
|
||||||
user = self.UserModel.objects.get(username='test')
|
user = self.UserModel.objects.get(pk=self.user.pk)
|
||||||
self.assertEqual(user.get_all_permissions() == set(['auth.test']), True)
|
self.assertEqual(user.get_all_permissions() == set(['auth.test']), True)
|
||||||
self.assertEqual(user.get_group_permissions(), set([]))
|
self.assertEqual(user.get_group_permissions(), set([]))
|
||||||
self.assertEqual(user.has_module_perms('Group'), False)
|
self.assertEqual(user.has_module_perms('Group'), False)
|
||||||
|
@ -71,7 +71,7 @@ class BaseModelBackendTest(object):
|
||||||
perm = Permission.objects.create(name='test3', content_type=content_type, codename='test3')
|
perm = Permission.objects.create(name='test3', content_type=content_type, codename='test3')
|
||||||
user.user_permissions.add(perm)
|
user.user_permissions.add(perm)
|
||||||
user.save()
|
user.save()
|
||||||
user = self.UserModel.objects.get(username='test')
|
user = self.UserModel.objects.get(pk=self.user.pk)
|
||||||
self.assertEqual(user.get_all_permissions(), set(['auth.test2', 'auth.test', 'auth.test3']))
|
self.assertEqual(user.get_all_permissions(), set(['auth.test2', 'auth.test', 'auth.test3']))
|
||||||
self.assertEqual(user.has_perm('test'), False)
|
self.assertEqual(user.has_perm('test'), False)
|
||||||
self.assertEqual(user.has_perm('auth.test'), True)
|
self.assertEqual(user.has_perm('auth.test'), True)
|
||||||
|
@ -81,7 +81,7 @@ class BaseModelBackendTest(object):
|
||||||
group.permissions.add(perm)
|
group.permissions.add(perm)
|
||||||
group.save()
|
group.save()
|
||||||
user.groups.add(group)
|
user.groups.add(group)
|
||||||
user = self.UserModel.objects.get(username='test')
|
user = self.UserModel.objects.get(pk=self.user.pk)
|
||||||
exp = set(['auth.test2', 'auth.test', 'auth.test3', 'auth.test_group'])
|
exp = set(['auth.test2', 'auth.test', 'auth.test3', 'auth.test_group'])
|
||||||
self.assertEqual(user.get_all_permissions(), exp)
|
self.assertEqual(user.get_all_permissions(), exp)
|
||||||
self.assertEqual(user.get_group_permissions(), set(['auth.test_group']))
|
self.assertEqual(user.get_group_permissions(), set(['auth.test_group']))
|
||||||
|
@ -93,7 +93,7 @@ class BaseModelBackendTest(object):
|
||||||
|
|
||||||
def test_has_no_object_perm(self):
|
def test_has_no_object_perm(self):
|
||||||
"""Regressiontest for #12462"""
|
"""Regressiontest for #12462"""
|
||||||
user = self.UserModel.objects.get(username='test')
|
user = self.UserModel.objects.get(pk=self.user.pk)
|
||||||
content_type = ContentType.objects.get_for_model(Group)
|
content_type = ContentType.objects.get_for_model(Group)
|
||||||
perm = Permission.objects.create(name='test', content_type=content_type, codename='test')
|
perm = Permission.objects.create(name='test', content_type=content_type, codename='test')
|
||||||
user.user_permissions.add(perm)
|
user.user_permissions.add(perm)
|
||||||
|
@ -106,7 +106,7 @@ class BaseModelBackendTest(object):
|
||||||
|
|
||||||
def test_get_all_superuser_permissions(self):
|
def test_get_all_superuser_permissions(self):
|
||||||
"A superuser has all permissions. Refs #14795"
|
"A superuser has all permissions. Refs #14795"
|
||||||
user = self.UserModel.objects.get(username='test2')
|
user = self.UserModel.objects.get(pk=self.superuser.pk)
|
||||||
self.assertEqual(len(user.get_all_permissions()), len(Permission.objects.all()))
|
self.assertEqual(len(user.get_all_permissions()), len(Permission.objects.all()))
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,12 +118,12 @@ class ModelBackendTest(BaseModelBackendTest, TestCase):
|
||||||
UserModel = User
|
UserModel = User
|
||||||
|
|
||||||
def create_users(self):
|
def create_users(self):
|
||||||
User.objects.create_user(
|
self.user = User.objects.create_user(
|
||||||
username='test',
|
username='test',
|
||||||
email='test@example.com',
|
email='test@example.com',
|
||||||
password='test',
|
password='test',
|
||||||
)
|
)
|
||||||
User.objects.create_superuser(
|
self.superuser = User.objects.create_superuser(
|
||||||
username='test2',
|
username='test2',
|
||||||
email='test2@example.com',
|
email='test2@example.com',
|
||||||
password='test',
|
password='test',
|
||||||
|
@ -151,13 +151,13 @@ class ExtensionUserModelBackendTest(BaseModelBackendTest, TestCase):
|
||||||
UserModel = ExtensionUser
|
UserModel = ExtensionUser
|
||||||
|
|
||||||
def create_users(self):
|
def create_users(self):
|
||||||
ExtensionUser.objects.create_user(
|
self.user = ExtensionUser.objects.create_user(
|
||||||
username='test',
|
username='test',
|
||||||
email='test@example.com',
|
email='test@example.com',
|
||||||
password='test',
|
password='test',
|
||||||
date_of_birth=date(2006, 4, 25)
|
date_of_birth=date(2006, 4, 25)
|
||||||
)
|
)
|
||||||
ExtensionUser.objects.create_superuser(
|
self.superuser = ExtensionUser.objects.create_superuser(
|
||||||
username='test2',
|
username='test2',
|
||||||
email='test2@example.com',
|
email='test2@example.com',
|
||||||
password='test',
|
password='test',
|
||||||
|
@ -165,6 +165,31 @@ class ExtensionUserModelBackendTest(BaseModelBackendTest, TestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@override_settings(AUTH_USER_MODEL='auth.CustomPermissionsUser')
|
||||||
|
class CustomPermissionsUserModelBackendTest(BaseModelBackendTest, TestCase):
|
||||||
|
"""
|
||||||
|
Tests for the ModelBackend using the CustomPermissionsUser model.
|
||||||
|
|
||||||
|
As with the ExtensionUser test, this isn't a perfect test, because both
|
||||||
|
the User and CustomPermissionsUser are synchronized to the database,
|
||||||
|
which wouldn't ordinary happen in production.
|
||||||
|
"""
|
||||||
|
|
||||||
|
UserModel = CustomPermissionsUser
|
||||||
|
|
||||||
|
def create_users(self):
|
||||||
|
self.user = CustomPermissionsUser.objects.create_user(
|
||||||
|
email='test@example.com',
|
||||||
|
password='test',
|
||||||
|
date_of_birth=date(2006, 4, 25)
|
||||||
|
)
|
||||||
|
self.superuser = CustomPermissionsUser.objects.create_superuser(
|
||||||
|
email='test2@example.com',
|
||||||
|
password='test',
|
||||||
|
date_of_birth=date(1976, 11, 8)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestObj(object):
|
class TestObj(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, AbstractUser, UserManager
|
from django.contrib.auth.models import (
|
||||||
|
BaseUserManager,
|
||||||
|
AbstractBaseUser,
|
||||||
|
AbstractUser,
|
||||||
|
UserManager,
|
||||||
|
PermissionsMixin
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# The custom User uses email as the unique identifier, and requires
|
# The custom User uses email as the unique identifier, and requires
|
||||||
|
@ -90,6 +96,40 @@ class ExtensionUser(AbstractUser):
|
||||||
app_label = 'auth'
|
app_label = 'auth'
|
||||||
|
|
||||||
|
|
||||||
|
# The CustomPermissionsUser users email as the identifier, but uses the normal
|
||||||
|
# Django permissions model. This allows us to check that the PermissionsMixin
|
||||||
|
# includes everything that is needed to interact with the ModelBackend.
|
||||||
|
|
||||||
|
class CustomPermissionsUserManager(CustomUserManager):
|
||||||
|
def create_superuser(self, email, password, date_of_birth):
|
||||||
|
u = self.create_user(email, password=password, date_of_birth=date_of_birth)
|
||||||
|
u.is_superuser = True
|
||||||
|
u.save(using=self._db)
|
||||||
|
return u
|
||||||
|
|
||||||
|
|
||||||
|
class CustomPermissionsUser(AbstractBaseUser, PermissionsMixin):
|
||||||
|
email = models.EmailField(verbose_name='email address', max_length=255, unique=True)
|
||||||
|
date_of_birth = models.DateField()
|
||||||
|
|
||||||
|
objects = CustomPermissionsUserManager()
|
||||||
|
|
||||||
|
USERNAME_FIELD = 'email'
|
||||||
|
REQUIRED_FIELDS = ['date_of_birth']
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
app_label = 'auth'
|
||||||
|
|
||||||
|
def get_full_name(self):
|
||||||
|
return self.email
|
||||||
|
|
||||||
|
def get_short_name(self):
|
||||||
|
return self.email
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return self.email
|
||||||
|
|
||||||
|
|
||||||
class IsActiveTestUser1(AbstractBaseUser):
|
class IsActiveTestUser1(AbstractBaseUser):
|
||||||
"""
|
"""
|
||||||
This test user class and derivatives test the default is_active behavior
|
This test user class and derivatives test the default is_active behavior
|
||||||
|
@ -104,4 +144,3 @@ class IsActiveTestUser1(AbstractBaseUser):
|
||||||
app_label = 'auth'
|
app_label = 'auth'
|
||||||
|
|
||||||
# the is_active attr is provided by AbstractBaseUser
|
# the is_active attr is provided by AbstractBaseUser
|
||||||
|
|
||||||
|
|
|
@ -2136,6 +2136,76 @@ override any of the definitions that refer to fields on
|
||||||
:class:`~django.contrib.auth.models.AbstractUser` that aren't on your
|
:class:`~django.contrib.auth.models.AbstractUser` that aren't on your
|
||||||
custom User class.
|
custom User class.
|
||||||
|
|
||||||
|
Custom users and permissions
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
To make it easy to include Django's permission framework into your own User
|
||||||
|
class, Django provides :class:`~django.contrib.auth.model.PermissionsMixin`.
|
||||||
|
This is an abstract model you can include in the class heirarchy for your User
|
||||||
|
model, giving you all the methods and database fields necessary to support
|
||||||
|
Django's permission model.
|
||||||
|
|
||||||
|
:class:`~django.contrib.auth.model.PermissionsMixin` provides the following
|
||||||
|
methods and attributes:
|
||||||
|
|
||||||
|
.. class:: models.PermissionsMixin
|
||||||
|
|
||||||
|
.. attribute:: models.PermissionsMixin.is_superuser
|
||||||
|
|
||||||
|
Boolean. Designates that this user has all permissions without
|
||||||
|
explicitly assigning them.
|
||||||
|
|
||||||
|
.. method:: models.PermissionsMixin.get_group_permissions(obj=None)
|
||||||
|
|
||||||
|
Returns a set of permission strings that the user has, through his/her
|
||||||
|
groups.
|
||||||
|
|
||||||
|
If ``obj`` is passed in, only returns the group permissions for
|
||||||
|
this specific object.
|
||||||
|
|
||||||
|
.. method:: models.PermissionsMixin.get_all_permissions(obj=None)
|
||||||
|
|
||||||
|
Returns a set of permission strings that the user has, both through
|
||||||
|
group and user permissions.
|
||||||
|
|
||||||
|
If ``obj`` is passed in, only returns the permissions for this
|
||||||
|
specific object.
|
||||||
|
|
||||||
|
.. method:: models.PermissionsMixin.has_perm(perm, obj=None)
|
||||||
|
|
||||||
|
Returns ``True`` if the user has the specified permission, where perm is
|
||||||
|
in the format ``"<app label>.<permission codename>"`` (see
|
||||||
|
`permissions`_). If the user is inactive, this method will
|
||||||
|
always return ``False``.
|
||||||
|
|
||||||
|
If ``obj`` is passed in, this method won't check for a permission for
|
||||||
|
the model, but for this specific object.
|
||||||
|
|
||||||
|
.. method:: models.PermissionsMixin.has_perms(perm_list, obj=None)
|
||||||
|
|
||||||
|
Returns ``True`` if the user has each of the specified permissions,
|
||||||
|
where each perm is in the format
|
||||||
|
``"<app label>.<permission codename>"``. If the user is inactive,
|
||||||
|
this method will always return ``False``.
|
||||||
|
|
||||||
|
If ``obj`` is passed in, this method won't check for permissions for
|
||||||
|
the model, but for the specific object.
|
||||||
|
|
||||||
|
.. method:: models.PermissionsMixin.has_module_perms(package_name)
|
||||||
|
|
||||||
|
Returns ``True`` if the user has any permissions in the given package
|
||||||
|
(the Django app label). If the user is inactive, this method will
|
||||||
|
always return ``False``.
|
||||||
|
|
||||||
|
.. admonition:: ModelBackend
|
||||||
|
|
||||||
|
If you don't include the
|
||||||
|
:class:`~django.contrib.auth.model.PermissionsMixin`, you must ensure you
|
||||||
|
don't invoke the permissions methods on ``ModelBackend``. ``ModelBackend``
|
||||||
|
assumes that certain fields are available on your user model. If your User
|
||||||
|
model doesn't provide those fields, you will receive database errors when
|
||||||
|
you check permissions.
|
||||||
|
|
||||||
Custom users and Proxy models
|
Custom users and Proxy models
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue