from django.contrib.auth.mixins import UserPassesTestMixin from django.core.exceptions import ImproperlyConfigured from django.core.paginator import Paginator from django.db.models import QuerySet # Boilerplate: https://git.zm.is/XF/django-crud-mixins # Edited to not undertake user= checks class StaffMemberRequiredMixin(UserPassesTestMixin): def test_func(self): return self.request.user.is_staff class RestrictedViewMixinStaff: """ This mixin overrides two helpers in order to pass the user object to the filters. get_queryset alters the objects returned for list views. get_form_kwargs passes the request object to the form class. Remaining permissions checks are in forms.py """ allow_empty = True queryset = None model = None paginate_by = None paginate_orphans = 0 context_object_name = None paginator_class = Paginator page_kwarg = "page" ordering = None def set_extra_args(self, user): """ This function is overriden to filter the objects by the requesting user. """ self.extra_permission_args = {} def get_queryset(self, **kwargs): """ This function is overriden to filter the objects by the requesting user. """ self.set_extra_args(self.request.user) if self.queryset is not None: queryset = self.queryset if isinstance(queryset, QuerySet): # queryset = queryset.all() # queryset = queryset.filter( # user=self.request.user, **self.extra_permission_args COMMENTED # ) queryset = queryset.filter(**self.extra_permission_args) elif self.model is not None: # queryset = self.model._default_manager.filter( # user=self.request.user, **self.extra_permission_args COMMENTED # ) queryset = self.model._default_manager.filter(**self.extra_permission_args) else: raise ImproperlyConfigured( "%(cls)s is missing a QuerySet. Define " "%(cls)s.model, %(cls)s.queryset, or override " "%(cls)s.get_queryset()." % {"cls": self.__class__.__name__} ) if hasattr(self, "get_ordering"): ordering = self.get_ordering() if ordering: if isinstance(ordering, str): ordering = (ordering,) queryset = queryset.order_by(*ordering) return queryset def get_form_kwargs(self): """Passes the request object to the form class. This is necessary to only display members that belong to a given user""" kwargs = super().get_form_kwargs() kwargs["request"] = self.request return kwargs class RestrictedFormMixinStaff: """ Just used to set the request object on the form class. """ fieldargs = {} # TODO: implement set_extra_args to check more permissions here # for completeness, however as views open forms, the permissions # are already checked there, so it may not be necessary. def __init__(self, *args, **kwargs): # self.fieldargs = {} self.request = kwargs.pop("request") super().__init__(*args, **kwargs) # for field in self.fields: # # Check it's not something like a CharField which has no queryset # if not hasattr(self.fields[field], "queryset"): # continue # model = self.fields[field].queryset.model # Check if the model has a user field # try: # model._meta.get_field("user") # # Add the user to the queryset filters # self.fields[field].queryset = model.objects.filter( # user=self.request.user, **self.fieldargs.get(field, {}) # ) # except FieldDoesNotExist: # pass