#32236 closed Cleanup/optimization (wontfix)
LoginRequiredMixin and PermissionRequiredMixin could use UserPassesTestMixin
| Reported by: | Jaap Roes | Owned by: | Jerin Peter George |
|---|---|---|---|
| Component: | contrib.auth | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | yes | UI/UX: | no |
Description
Currently django.contrib.auth.mixins defines LoginRequiredMixin and PermissionRequiredMixin as subclasses of AccessMixin.
It also defines an abstract UserPassesTestMixin that requires an implementation of test_func (or get_test_func).
Both LoginRequiredMixin and PermissionRequiredMixin perform tests on the current user and could be implemented subclasses of UserPassesTestMixin with an implementation of test_func (or get_test_func). That way they can re-use the dispatch logic in UserPassesTestMixin.
i.e.:
class LoginRequiredMixin(UserPassesTestMixin):
def test_func(self):
return self.request.user.is_authenticated
class PermissionRequiredMixin(UserPassesTestMixin):
"""Verify that the current user has all specified permissions."""
permission_required = None
def get_permission_required(self):
"""
Override this method to override the permission_required attribute.
Must return an iterable.
"""
if self.permission_required is None:
raise ImproperlyConfigured(
'{0} is missing the permission_required attribute. Define {0}.permission_required, or override '
'{0}.get_permission_required().'.format(self.__class__.__name__)
)
if isinstance(self.permission_required, str):
perms = (self.permission_required,)
else:
perms = self.permission_required
return perms
def has_permission(self):
"""
Override this method to customize the way permissions are checked.
"""
perms = self.get_permission_required()
return self.request.user.has_perms(perms)
def get_test_func(self):
return self.has_permission
Change History (7)
comment:1 by , 5 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
comment:2 by , 5 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:4 by , 5 years ago
I would like to write the related docs, but I wish to know whether my implementations are okay or not.
comment:5 by , 5 years ago
| Patch needs improvement: | set |
|---|
comment:6 by , 5 years ago
| Has patch: | unset |
|---|---|
| Patch needs improvement: | unset |
| Resolution: | → wontfix |
| Status: | assigned → closed |
Unfortunately, due to the way UserPassesTestMixin is implemented, you cannot stack them in your inheritance list, so LoginRequiredMixin/PermissionRequiredMixin cannot subclass it, see Stacking UserPassesTestMixin.
comment:7 by , 5 years ago
Oh wow, I didn't realize this was a known flaw in the design of UserPassesTestMixin, sorry for the noise.
PR: https://github.com/django/django/pull/13747