Proposal: PermissionRequiredMethodMixin
martinlehoux opened this issue · comments
Hello !
As I was using django-rules
in a project, I need to use different permissions for the same view, depending on the method used. My use case is very simple : instead of having a DetailView
and an UpdateView
, I only use UpdateView, but the page GET purpose is to display the detail (the form is hidden in a modal). So I wanted to enable to enable GET for this UpdateView for "track.view_track"
permission, but the POST only for "track.edit_track"
.
I couldn't find in the documentation how to do so, so I ended up with this new class base view mixin. I wrote it inspired by django.auth.contrib.mixins.PermissionRequireMixin
and rules.contrib.views.PermissionRequiredMixin
. I thought it was generic enough to propose it here.
Maybe I have missed an already existing implementation, so don't hesitate to tell me !
class TrackDetailView(PermissionRequiredMethodMixin, generic.UpdateView):
permission_required_map = {
"GET": "track.view_track",
"POST": "track.edit_track",
}
class PermissionRequiredMethodMixin(PermissionRequiredMixin):
permission_required_map: Dict[str, Union[str, Tuple[str]]] = None
def get_permission_required(self):
if self.permission_required_map is not None:
if not isinstance(self.permission_required_map, dict):
raise ImproperlyConfigured(
f"{self.__class__.__name__} has a wrong permission_required_map attribute. "
"It should be a mapping from http method to permission."
)
perms = self.permission_required_map.get(self.request.method)
if perms is not None:
return (perms,) if isinstance(perms, str) else perms
return super().get_permission_required()