From fb520d6f92c4537b4f449d04d3071cc7fc2d084b Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Fri, 14 Jul 2017 05:19:50 -0400 Subject: [PATCH] Add view mixin to make sure a subclass can't override its parent's get_queryset method. Signed-off-by: Roberto Rosario --- mayan/apps/common/generics.py | 9 ++++---- mayan/apps/common/mixins.py | 24 ++++++++++++++++++-- mayan/apps/documents/views/document_views.py | 3 +-- mayan/apps/linking/views.py | 3 +-- mayan/apps/tags/views.py | 3 +-- 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/mayan/apps/common/generics.py b/mayan/apps/common/generics.py index b4dd86c7a0..c8142852cb 100644 --- a/mayan/apps/common/generics.py +++ b/mayan/apps/common/generics.py @@ -25,7 +25,7 @@ from .mixins import ( DeleteExtraDataMixin, DynamicFormViewMixin, ExtraContextMixin, FormExtraKwargsMixin, MultipleObjectMixin, ObjectActionMixin, ObjectListPermissionFilterMixin, ObjectNameMixin, - ObjectPermissionCheckMixin, RedirectionMixin, + ObjectPermissionCheckMixin, PreserveGetQuerysetMixin, RedirectionMixin, ViewPermissionCheckMixin ) @@ -282,12 +282,11 @@ class MultiFormView(DjangoFormView): return self.forms_invalid(forms) -class MultipleObjectFormActionView(ObjectActionMixin, MultipleObjectMixin, FormExtraKwargsMixin, ViewPermissionCheckMixin, ExtraContextMixin, RedirectionMixin, DjangoFormView): +class MultipleObjectFormActionView(PreserveGetQuerysetMixin, ObjectActionMixin, MultipleObjectMixin, FormExtraKwargsMixin, ViewPermissionCheckMixin, ExtraContextMixin, RedirectionMixin, DjangoFormView): """ This view will present a form and upon receiving a POST request will perform an action on an object or queryset """ - template_name = 'appearance/generic_form.html' def form_valid(self, form): @@ -295,7 +294,7 @@ class MultipleObjectFormActionView(ObjectActionMixin, MultipleObjectMixin, FormE return super(MultipleObjectFormActionView, self).form_valid(form=form) -class MultipleObjectConfirmActionView(ObjectActionMixin, MultipleObjectMixin, ViewPermissionCheckMixin, ExtraContextMixin, RedirectionMixin, TemplateView): +class MultipleObjectConfirmActionView(ObjectActionMixin, MultipleObjectMixin, ObjectListPermissionFilterMixin, ViewPermissionCheckMixin, ExtraContextMixin, RedirectionMixin, TemplateView): template_name = 'appearance/generic_confirm.html' def post(self, request, *args, **kwargs): @@ -459,7 +458,7 @@ class SingleObjectDynamicFormEditView(DynamicFormViewMixin, SingleObjectEditView pass -class SingleObjectListView(PaginationMixin, ViewPermissionCheckMixin, ObjectListPermissionFilterMixin, ExtraContextMixin, RedirectionMixin, ListView): +class SingleObjectListView(PreserveGetQuerysetMixin, PaginationMixin, ViewPermissionCheckMixin, ObjectListPermissionFilterMixin, ExtraContextMixin, RedirectionMixin, ListView): template_name = 'appearance/generic_list.html' def get_paginate_by(self, queryset): diff --git a/mayan/apps/common/mixins.py b/mayan/apps/common/mixins.py index 712b22c343..6a302880d4 100644 --- a/mayan/apps/common/mixins.py +++ b/mayan/apps/common/mixins.py @@ -18,8 +18,8 @@ __all__ = ( 'DeleteExtraDataMixin', 'DynamicFormViewMixin', 'ExtraContextMixin', 'FormExtraKwargsMixin', 'MultipleObjectMixin', 'ObjectActionMixin', 'ObjectListPermissionFilterMixin', 'ObjectNameMixin', - 'ObjectPermissionCheckMixin', 'RedirectionMixin', - 'ViewPermissionCheckMixin' + 'ObjectPermissionCheckMixin', 'PreserveGetQuerysetMixin', + 'RedirectionMixin', 'ViewPermissionCheckMixin' ) @@ -266,6 +266,26 @@ class ObjectPermissionCheckMixin(object): ).dispatch(request, *args, **kwargs) +class PreserveGetQuerysetMixin(object): + """ + Allows class based views to define a get_queryset method that doesn't + overrided the parent classe's get_queryset method + """ + def __init__(self, *args, **kwargs): + result = super(PreserveGetQuerysetMixin, self).__init__(*args, **kwargs) + if not hasattr(self.__class__, 'original_get_queryset'): + if not self.__class__.mro()[0].get_queryset == PreserveGetQuerysetMixin.get_queryset: + setattr(self.__class__, 'original_get_queryset', self.__class__.mro()[0].get_queryset) + self.__class__.mro()[0].get_queryset = PreserveGetQuerysetMixin.get_queryset + return result + + def get_queryset(self, *args, **kwargs): + if hasattr(self.__class__, 'original_get_queryset'): + self.queryset = self.__class__.original_get_queryset(self, *args, **kwargs) + + return super(PreserveGetQuerysetMixin, self).get_queryset(*args, **kwargs) + + class RedirectionMixin(object): post_action_redirect = None action_cancel_redirect = None diff --git a/mayan/apps/documents/views/document_views.py b/mayan/apps/documents/views/document_views.py index fd284baa49..73a05b6391 100644 --- a/mayan/apps/documents/views/document_views.py +++ b/mayan/apps/documents/views/document_views.py @@ -63,8 +63,7 @@ class DocumentListView(SingleObjectListView): } def get_queryset(self): - self.queryset = self.get_document_queryset().filter(is_stub=False) - return super(DocumentListView, self).get_queryset() + return self.get_document_queryset().filter(is_stub=False) class DeletedDocumentListView(DocumentListView): diff --git a/mayan/apps/linking/views.py b/mayan/apps/linking/views.py index c2201be3c4..776a84d1a1 100644 --- a/mayan/apps/linking/views.py +++ b/mayan/apps/linking/views.py @@ -133,8 +133,7 @@ class SmartLinkListView(SingleObjectListView): } def get_queryset(self): - self.queryset = self.get_smart_link_queryset() - return super(SmartLinkListView, self).get_queryset() + return self.get_smart_link_queryset() def get_smart_link_queryset(self): return SmartLink.objects.all() diff --git a/mayan/apps/tags/views.py b/mayan/apps/tags/views.py index a31e80437a..9c378ad38a 100644 --- a/mayan/apps/tags/views.py +++ b/mayan/apps/tags/views.py @@ -182,8 +182,7 @@ class TagListView(SingleObjectListView): } def get_queryset(self): - self.queryset = self.get_tag_queryset() - return super(TagListView, self).get_queryset() + return self.get_tag_queryset() def get_tag_queryset(self): return Tag.objects.all()