diff --git a/core/views/__init__.py b/core/views/__init__.py index 10529bd..b322311 100644 --- a/core/views/__init__.py +++ b/core/views/__init__.py @@ -15,6 +15,10 @@ from core.util import logs log = logs.get_logger(__name__) +class AbortSave(Exception): + pass + + class RestrictedViewMixin: """ This mixin overrides two helpers in order to pass the user object to the filters. @@ -33,17 +37,28 @@ class RestrictedViewMixin: 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) + queryset = queryset.filter( + user=self.request.user, **self.extra_permission_args + ) elif self.model is not None: - queryset = self.model._default_manager.filter(user=self.request.user) + queryset = self.model._default_manager.filter( + user=self.request.user, **self.extra_permission_args + ) else: raise ImproperlyConfigured( "%(cls)s is missing a QuerySet. Define " @@ -99,6 +114,7 @@ class ObjectList(RestrictedViewMixin, ObjectNameMixin, ListView): list_url_args = ["type"] submit_url_name = None + submit_url_args = ["type"] delete_all_url_name = None widget_options = None @@ -146,6 +162,13 @@ class ObjectList(RestrictedViewMixin, ObjectNameMixin, ListView): if is_empty: raise Http404("Empty list") + submit_url_args = {} + for arg in self.submit_url_args: + if arg in locals(): + submit_url_args[arg] = locals()[arg] + elif arg in kwargs: + submit_url_args[arg] = kwargs[arg] + context = self.get_context_data() context["title"] = self.title + f" ({type})" context["title_singular"] = self.title_singular @@ -159,7 +182,9 @@ class ObjectList(RestrictedViewMixin, ObjectNameMixin, ListView): context["context_object_name_singular"] = self.context_object_name_singular if self.submit_url_name is not None: - context["submit_url"] = reverse(self.submit_url_name, kwargs={"type": type}) + context["submit_url"] = reverse( + self.submit_url_name, kwargs=submit_url_args + ) if self.list_url_name is not None: context["list_url"] = reverse(self.list_url_name, kwargs=list_url_args) @@ -204,11 +229,19 @@ class ObjectCreate(RestrictedViewMixin, ObjectNameMixin, CreateView): def post_save(self, obj): pass + def pre_save_mutate(self, user, obj): + pass + def form_valid(self, form): obj = form.save(commit=False) if self.request is None: raise Exception("Request is None") obj.user = self.request.user + try: + self.pre_save_mutate(self.request.user, obj) + except AbortSave as e: + context = {"message": f"Failed to save: {e}", "class": "danger"} + return self.render_to_response(context) obj.save() form.save_m2m() self.post_save(obj)