diff --git a/mayan/apps/common/generics.py b/mayan/apps/common/generics.py index ad97a5123c..1da7d651cd 100644 --- a/mayan/apps/common/generics.py +++ b/mayan/apps/common/generics.py @@ -22,9 +22,9 @@ from .mixins import ( from .settings import setting_paginate_by __all__ = ( - 'AssignRemoveView', 'ConfirmView', 'MultiFormView', 'ParentChildListView', - 'SingleObjectCreateView', 'SingleObjectDeleteView', - 'SingleObjectEditView', 'SingleObjectListView', 'SimpleView', + 'AssignRemoveView', 'ConfirmView', 'MultiFormView', + 'SingleObjectCreateView', 'SingleObjectDeleteView', 'SingleObjectEditView', + 'SingleObjectListView', 'SimpleView', ) @@ -245,89 +245,6 @@ class MultiFormView(FormView): return self.forms_invalid(forms) -class ParentChildListView(ViewPermissionCheckMixin, ObjectPermissionCheckMixin, ExtraContextMixin, ListView, SingleObjectMixin): - parent_model = None - parent_queryset = None - template_name = 'appearance/generic_list.html' - - def get(self, request, *args, **kwargs): - # Parent - self.object = self.get_object() - - # Children - self.object_list = self.get_queryset() - allow_empty = self.get_allow_empty() - if not allow_empty: - # When pagination is enabled and object_list is a queryset, - # it's better to do a cheap query than to load the unpaginated - # queryset in memory. - if (self.get_paginate_by(self.object_list) is not None - and hasattr(self.object_list, 'exists')): - is_empty = not self.object_list.exists() - else: - is_empty = len(self.object_list) == 0 - if is_empty: - raise Http404( - _( - "Empty list and '%(class_name)s.allow_empty' is False." - ) % { - 'class_name': self.__class__.__name__ - } - ) - - context = self.get_context_data(object=self.object) - return self.render_to_response(context) - - def get_object(self, queryset=None): - # Use a custom queryset if provided; this is required for subclasses - # like DateDetailView - if queryset is None: - queryset = self.get_parent_queryset() - # Next, try looking up by primary key. - pk = self.kwargs.get(self.pk_url_kwarg, None) - slug = self.kwargs.get(self.slug_url_kwarg, None) - if pk is not None: - queryset = queryset.filter(pk=pk) - # Next, try looking up by slug. - if slug is not None and (pk is None or self.query_pk_and_slug): - slug_field = self.get_slug_field() - queryset = queryset.filter(**{slug_field: slug}) - # If none of those are defined, it's an error. - if pk is None and slug is None: - raise AttributeError("Generic detail view %s must be called with " - "either an object pk or a slug." - % self.__class__.__name__) - try: - # Get the single item from the filtered queryset - obj = queryset.get() - except queryset.model.DoesNotExist: - raise Http404(_("No %(verbose_name)s found matching the query") % - {'verbose_name': queryset.model._meta.verbose_name}) - return obj - - def get_parent_queryset(self): - """ - Return the `QuerySet` that will be used to look up the object. - Note that this method is called by the default implementation of - `get_object` and may not be called if `get_object` is overridden. - """ - if self.parent_queryset is None: - if self.parent_model: - return self.model._default_manager.all() - else: - raise ImproperlyConfigured( - "%(cls)s is missing a QuerySet. Define " - "%(cls)s.parent_model, %(cls)s.parent_queryset, or override " - "%(cls)s.get_parent_queryset()." % { - 'cls': self.__class__.__name__ - } - ) - return self.parent_queryset.all() - - def get_queryset(self): - raise NotImplementedError - - class SimpleView(ViewPermissionCheckMixin, ExtraContextMixin, TemplateView): pass diff --git a/mayan/apps/documents/views.py b/mayan/apps/documents/views.py index 3a0440c389..ed53ca2616 100644 --- a/mayan/apps/documents/views.py +++ b/mayan/apps/documents/views.py @@ -16,12 +16,12 @@ from django.utils.translation import ugettext_lazy as _, ungettext from acls.models import AccessControlList from common.compressed_files import CompressedFile +from common.generics import ( + ConfirmView, SingleObjectCreateView, SingleObjectDeleteView, + SingleObjectEditView, SingleObjectListView +) from common.mixins import MultipleInstanceActionMixin from common.utils import encapsulate, pretty_size -from common.views import ( - ConfirmView, ParentChildListView, SingleObjectCreateView, - SingleObjectDeleteView, SingleObjectEditView, SingleObjectListView -) from common.widgets import two_state_template from converter.literals import ( DEFAULT_PAGE_NUMBER, DEFAULT_ROTATION, DEFAULT_ZOOM_LEVEL @@ -185,23 +185,31 @@ class DocumentManyRestoreView(MultipleInstanceActionMixin, DocumentRestoreView): model = DeletedDocument -class DocumentPageListView(ParentChildListView): - object_permission = permission_document_view - parent_queryset = Document.objects.all() +class DocumentPageListView(SingleObjectListView): + def dispatch(self, request, *args, **kwargs): + try: + Permission.check_permissions( + self.request.user, (permission_document_view,) + ) + except PermissionDenied: + AccessControlList.objects.check_access( + permission_document_view, self.request.user, self.get_document() + ) + + return super( + DocumentPageListView, self + ).dispatch(request, *args, **kwargs) + + def get_document(self): + return get_object_or_404(Document, pk=self.kwargs['pk']) def get_queryset(self): - return self.get_object().pages.all() + return self.get_document().pages.all() - def get_context_data(self, **kwargs): - context = super(DocumentPageListView, self).get_context_data(**kwargs) - - context.update( - { - 'title': _('Pages for document: %s') % self.get_object(), - } - ) - - return context + def get_extra_context(self): + return { + 'title': _('Pages for document: %s') % self.get_document(), + } class DocumentTypeDocumentListView(DocumentListView): diff --git a/mayan/apps/sources/views.py b/mayan/apps/sources/views.py index b81701f0b1..b264cb748b 100644 --- a/mayan/apps/sources/views.py +++ b/mayan/apps/sources/views.py @@ -15,8 +15,8 @@ from common import menu_facet from common.models import SharedUploadedFile from common.utils import encapsulate from common.views import ( - MultiFormView, ParentChildListView, SingleObjectCreateView, - SingleObjectDeleteView, SingleObjectEditView, SingleObjectListView + MultiFormView, SingleObjectCreateView, SingleObjectDeleteView, + SingleObjectEditView, SingleObjectListView ) from common.widgets import two_state_template from documents.models import DocumentType, Document @@ -47,34 +47,30 @@ from .tasks import task_source_handle_upload from .utils import get_class, get_form_class, get_upload_form_class -class SourceLogListView(ParentChildListView): - object_permission = permission_sources_setup_view - parent_queryset = Source.objects.select_subclasses() +class SourceLogListView(SingleObjectListView): + view_permission = permission_sources_setup_view + + def get_source(self): + return get_object_or_404(Source.objects.select_subclasses(), pk=self.kwargs['pk']) def get_queryset(self): - return self.get_object().logs.all() + return self.get_source().logs.all() - def get_context_data(self, **kwargs): - context = super(SourceLogListView, self).get_context_data(**kwargs) - - context.update( - { - 'title': _('Log entries for source: %s') % self.get_object(), - 'hide_object': True, - 'extra_columns': [ - { - 'name': _('Date time'), - 'attribute': encapsulate(lambda entry: entry.datetime) - }, - { - 'name': _('Message'), - 'attribute': encapsulate(lambda entry: entry.message) - }, - ] - } - ) - - return context + def get_extra_context(self): + return { + 'title': _('Log entries for source: %s') % self.get_source(), + 'hide_object': True, + 'extra_columns': ( + { + 'name': _('Date time'), + 'attribute': encapsulate(lambda entry: entry.datetime) + }, + { + 'name': _('Message'), + 'attribute': encapsulate(lambda entry: entry.message) + }, + ) + } def document_create_siblings(request, document_id): @@ -397,9 +393,9 @@ class UploadInteractiveVersionView(UploadBaseView): def staging_file_delete(request, staging_folder_pk, encoded_filename): Permission.check_permissions( - request.user, [ + request.user, ( permission_document_create, permission_document_new_version - ] + ) ) staging_folder = get_object_or_404( StagingFolderSource, pk=staging_folder_pk