diff --git a/mayan/apps/metadata/api_views.py b/mayan/apps/metadata/api_views.py index f23a518bca..042b8a903e 100644 --- a/mayan/apps/metadata/api_views.py +++ b/mayan/apps/metadata/api_views.py @@ -14,8 +14,8 @@ from mayan.apps.rest_api.permissions import MayanPermission from .models import MetadataType from .permissions import ( - permission_document_metadata_add, permission_document_metadata_remove, - permission_document_metadata_edit, permission_document_metadata_view, + permission_metadata_add, permission_metadata_remove, + permission_metadata_edit, permission_metadata_view, permission_metadata_type_create, permission_metadata_type_delete, permission_metadata_type_edit, permission_metadata_type_view ) @@ -34,9 +34,9 @@ class APIDocumentMetadataListView(generics.ListCreateAPIView): """ def get_document(self): if self.request.method == 'GET': - permission_required = permission_document_metadata_view + permission_required = permission_metadata_view else: - permission_required = permission_document_metadata_add + permission_required = permission_metadata_add document = get_object_or_404( klass=Document, pk=self.kwargs['document_pk'] @@ -90,13 +90,13 @@ class APIDocumentMetadataView(generics.RetrieveUpdateDestroyAPIView): def get_document(self): if self.request.method == 'GET': - permission_required = permission_document_metadata_view + permission_required = permission_metadata_view elif self.request.method == 'PUT': - permission_required = permission_document_metadata_edit + permission_required = permission_metadata_edit elif self.request.method == 'PATCH': - permission_required = permission_document_metadata_edit + permission_required = permission_metadata_edit elif self.request.method == 'DELETE': - permission_required = permission_document_metadata_remove + permission_required = permission_metadata_remove document = get_object_or_404( klass=Document, pk=self.kwargs['document_pk'] diff --git a/mayan/apps/metadata/apps.py b/mayan/apps/metadata/apps.py index 6058d3b977..99d227ccd8 100644 --- a/mayan/apps/metadata/apps.py +++ b/mayan/apps/metadata/apps.py @@ -48,8 +48,8 @@ from .links import ( ) from .methods import method_get_metadata from .permissions import ( - permission_document_metadata_add, permission_document_metadata_edit, - permission_document_metadata_remove, permission_document_metadata_view, + permission_metadata_add, permission_metadata_edit, + permission_metadata_remove, permission_metadata_view, permission_metadata_type_delete, permission_metadata_type_edit, permission_metadata_type_view ) @@ -130,10 +130,10 @@ class MetadataApp(MayanAppConfig): ModelPermission.register( model=Document, permissions=( - permission_document_metadata_add, - permission_document_metadata_edit, - permission_document_metadata_remove, - permission_document_metadata_view, + permission_metadata_add, + permission_metadata_edit, + permission_metadata_remove, + permission_metadata_view, ) ) ModelPermission.register( diff --git a/mayan/apps/metadata/links.py b/mayan/apps/metadata/links.py index b2b187578e..a93fea2e1a 100644 --- a/mayan/apps/metadata/links.py +++ b/mayan/apps/metadata/links.py @@ -15,32 +15,32 @@ from .icons import ( icon_metadata_type_edit, icon_metadata_type_list ) from .permissions import ( - permission_document_metadata_add, permission_document_metadata_edit, - permission_document_metadata_remove, permission_document_metadata_view, + permission_metadata_add, permission_metadata_edit, + permission_metadata_remove, permission_metadata_view, permission_metadata_type_create, permission_metadata_type_delete, permission_metadata_type_edit, permission_metadata_type_view ) link_document_metadata_add = Link( icon_class=icon_document_metadata_add, kwargs={'document_id': 'object.pk'}, - permission=permission_document_metadata_add, text=_('Add metadata'), + permission=permission_metadata_add, text=_('Add metadata'), view='metadata:document_metadata_add', ) link_document_metadata_edit = Link( icon_class=icon_document_metadata_edit, kwargs={'document_id': 'object.pk'}, - permission=permission_document_metadata_edit, text=_('Edit metadata'), + permission=permission_metadata_edit, text=_('Edit metadata'), view='metadata:document_metadata_edit' ) link_document_metadata_remove = Link( icon_class=icon_document_metadata_remove, kwargs={'document_id': 'object.pk'}, - permission=permission_document_metadata_remove, + permission=permission_metadata_remove, text=_('Remove metadata'), view='metadata:document_metadata_remove' ) link_document_metadata_view = Link( icon_class=icon_document_metadata_view, kwargs={'document_id': 'resolved_object.pk'}, - permission=permission_document_metadata_view, text=_('Metadata'), + permission=permission_metadata_view, text=_('Metadata'), view='metadata:document_metadata_view' ) link_document_multiple_metadata_add = Link( diff --git a/mayan/apps/metadata/permissions.py b/mayan/apps/metadata/permissions.py index e1c35fa460..d1ec76f894 100644 --- a/mayan/apps/metadata/permissions.py +++ b/mayan/apps/metadata/permissions.py @@ -6,16 +6,16 @@ from mayan.apps.permissions import PermissionNamespace namespace = PermissionNamespace(label=_('Metadata'), name='metadata') -permission_document_metadata_add = namespace.add_permission( +permission_metadata_add = namespace.add_permission( label=_('Add metadata to a document'), name='metadata_document_add' ) -permission_document_metadata_edit = namespace.add_permission( +permission_metadata_edit = namespace.add_permission( label=_('Edit a document\'s metadata'), name='metadata_document_edit' ) -permission_document_metadata_remove = namespace.add_permission( +permission_metadata_remove = namespace.add_permission( label=_('Remove metadata from a document'), name='metadata_document_remove' ) -permission_document_metadata_view = namespace.add_permission( +permission_metadata_view = namespace.add_permission( label=_('View metadata from a document'), name='metadata_document_view' ) diff --git a/mayan/apps/metadata/tests/test_api.py b/mayan/apps/metadata/tests/test_api.py index 9092c0c3ad..860d09f7ab 100644 --- a/mayan/apps/metadata/tests/test_api.py +++ b/mayan/apps/metadata/tests/test_api.py @@ -11,8 +11,8 @@ from mayan.apps.rest_api.tests import BaseAPITestCase from ..models import DocumentTypeMetadataType, MetadataType from ..permissions import ( - permission_document_metadata_add, permission_document_metadata_edit, - permission_document_metadata_remove, permission_document_metadata_view, + permission_metadata_add, permission_metadata_edit, + permission_metadata_remove, permission_metadata_view, permission_metadata_type_create, permission_metadata_type_delete, permission_metadata_type_edit, permission_metadata_type_view ) @@ -377,7 +377,7 @@ class DocumentMetadataAPITestCase(BaseAPITestCase): self.assertEqual(self.document.metadata.count(), 0) def test_document_metadata_create_view_with_access(self): - self.grant_access(permission=permission_document_metadata_add, obj=self.document) + self.grant_access(permission=permission_metadata_add, obj=self.document) response = self._request_document_metadata_create_view() self.assertEqual(response.status_code, status.HTTP_201_CREATED) document_metadata = self.document.metadata.first() @@ -387,7 +387,7 @@ class DocumentMetadataAPITestCase(BaseAPITestCase): def test_document_metadata_create_duplicate_view(self): self._create_document_metadata() - self.grant_permission(permission=permission_document_metadata_add) + self.grant_permission(permission=permission_metadata_add) response = self._request_document_metadata_create_view() self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(list(response.data.keys())[0], 'non_field_errors') @@ -395,7 +395,7 @@ class DocumentMetadataAPITestCase(BaseAPITestCase): def test_document_metadata_create_invalid_lookup_value_view(self): self.metadata_type.lookup = 'invalid,lookup,values,on,purpose' self.metadata_type.save() - self.grant_permission(permission=permission_document_metadata_add) + self.grant_permission(permission=permission_metadata_add) response = self._request_document_metadata_create_view() self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(list(response.data.keys())[0], 'non_field_errors') @@ -418,7 +418,7 @@ class DocumentMetadataAPITestCase(BaseAPITestCase): def test_document_metadata_delete_view_with_access(self): self._create_document_metadata() self.grant_access( - permission=permission_document_metadata_remove, obj=self.document + permission=permission_metadata_remove, obj=self.document ) response = self._request_document_metadata_delete_view() self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) @@ -438,7 +438,7 @@ class DocumentMetadataAPITestCase(BaseAPITestCase): def test_document_metadata_list_view_with_access(self): self._create_document_metadata() self.grant_access( - permission=permission_document_metadata_view, obj=self.document + permission=permission_metadata_view, obj=self.document ) response = self._request_document_metadata_list_view() self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -477,7 +477,7 @@ class DocumentMetadataAPITestCase(BaseAPITestCase): def test_document_metadata_patch_view_with_access(self): self._create_document_metadata() self.grant_access( - permission=permission_document_metadata_edit, obj=self.document + permission=permission_metadata_edit, obj=self.document ) response = self._request_document_metadata_edit_view_via_patch() self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -510,7 +510,7 @@ class DocumentMetadataAPITestCase(BaseAPITestCase): def test_document_metadata_put_view_with_access(self): self._create_document_metadata() self.grant_access( - permission=permission_document_metadata_edit, obj=self.document + permission=permission_metadata_edit, obj=self.document ) response = self._request_document_metadata_edit_view_via_put() self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/mayan/apps/metadata/tests/test_events.py b/mayan/apps/metadata/tests/test_events.py index 75d8e30ecf..70027cd36c 100644 --- a/mayan/apps/metadata/tests/test_events.py +++ b/mayan/apps/metadata/tests/test_events.py @@ -38,7 +38,7 @@ class MetadataTypeEventsTestCase(MetadataTestsMixin, GenericDocumentViewTestCase self.assertEqual(event.verb, event_metadata_type_created.id) self.assertEqual(event.target, metadata_type) - self.assertEqual(event.actor, self.user) + self.assertEqual(event.actor, self._test_case_user) def test_metadata_type_edit_event_no_permissions(self): self._create_metadata_type() @@ -66,4 +66,4 @@ class MetadataTypeEventsTestCase(MetadataTestsMixin, GenericDocumentViewTestCase self.assertEqual(event.verb, event_metadata_type_edited.id) self.assertEqual(event.target, self.metadata_type) - self.assertEqual(event.actor, self.user) + self.assertEqual(event.actor, self._test_case_user) diff --git a/mayan/apps/metadata/tests/test_views.py b/mayan/apps/metadata/tests/test_views.py index f483319b92..a4a457ced4 100644 --- a/mayan/apps/metadata/tests/test_views.py +++ b/mayan/apps/metadata/tests/test_views.py @@ -2,6 +2,8 @@ from __future__ import unicode_literals import logging +from django.utils.encoding import force_text + from mayan.apps.common.tests import GenericViewTestCase from mayan.apps.documents.models import DocumentType from mayan.apps.documents.permissions import ( @@ -13,8 +15,8 @@ from mayan.apps.documents.tests import ( from ..models import MetadataType from ..permissions import ( - permission_document_metadata_add, permission_document_metadata_remove, - permission_document_metadata_edit, permission_metadata_type_create, + permission_metadata_add, permission_metadata_remove, + permission_metadata_edit, permission_metadata_type_create, permission_metadata_type_delete, permission_metadata_type_edit, permission_metadata_type_view ) @@ -28,51 +30,114 @@ from .literals import ( from .mixins import MetadataTestsMixin -class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): +class DocumentMetadataViewTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): def setUp(self): - super(DocumentMetadataTestCase, self).setUp() - self.login_user() + super(DocumentMetadataViewTestCase, self).setUp() self._create_metadata_type() self.document_type.metadata.create(metadata_type=self.metadata_type) - def _request_get_document_metadata_add_view(self): + def _request_document_metadata_add_get_view(self): return self.get( viewname='metadata:document_metadata_add', - kwargs={'document_id': self.document.pk}, + kwargs={'document_id': self.test_document.pk}, ) - def _request_post_document_metadata_add_view(self): + def _request_document_multiple_metadata_add_get_view(self): + return self.get( + viewname='metadata:document_multiple_metadata_add', + data={'id_list': ','.join([force_text(pk) for pk in self.id_list])}, + ) + + def _request_document_metadata_add_post_view(self): return self.post( viewname='metadata:document_metadata_add', - kwargs={'document_id': self.document.pk}, + kwargs={'document_id': self.test_document.pk}, data={'metadata_type': self.metadata_type.pk} ) - def test_document_metadata_add_view_no_permission(self): - response = self._request_get_document_metadata_add_view() + def test_document_metadata_add_get_view_no_permission(self): + response = self._request_document_metadata_add_get_view() self.assertNotContains( - response, text=self.metadata_type.label, status_code=200 + response, text=self.metadata_type.label, status_code=404 ) - response = self._request_post_document_metadata_add_view() - self.assertEqual(response.status_code, 200) - - self.assertEqual(len(self.document.metadata.all()), 0) - - def test_document_metadata_add_view_with_document_access(self): + def test_document_metadata_add_get_view_with_full_access(self): self.grant_access( - permission=permission_document_metadata_add, obj=self.document + obj=self.test_document, permission=permission_metadata_add ) - response = self._request_get_document_metadata_add_view() + response = self._request_document_metadata_add_get_view() self.assertContains( response, text=self.metadata_type.label, status_code=200 ) - response = self._request_post_document_metadata_add_view() + def test_document_individual_metadata_same_type_mixin_with_access(self): + self.grant_access( + obj=self.test_document, permission=permission_metadata_add + ) + + self._create_document_type_random() + self.test_document_type.metadata.create(metadata_type=self.metadata_type) + self._create_document() + self.grant_access( + obj=self.test_document, permission=permission_metadata_add + ) + + response = self._request_document_metadata_add_get_view() + self.assertContains( + response, text=self.metadata_type.label, status_code=200 + ) + + def test_document_single_metadata_same_type_mixin_with_access(self): + self.id_list = [self.test_document.pk] + self.grant_access( + obj=self.test_document, permission=permission_metadata_add + ) + + self._create_document_type_random() + self.test_document_type.metadata.create(metadata_type=self.metadata_type) + self._create_document() + self.grant_access( + obj=self.test_document, permission=permission_metadata_add + ) + + response = self._request_document_multiple_metadata_add_get_view() + self.assertContains( + response, text=self.metadata_type.label, status_code=200 + ) + + def test_document_multiple_metadata_same_type_mixin_with_access(self): + self.id_list = [self.test_document.pk] + self.grant_access( + obj=self.test_document, permission=permission_metadata_add + ) + + self._create_document_type_random() + self.test_document_type.metadata.create(metadata_type=self.metadata_type) + self._create_document() + self.id_list.append(self.test_document.pk) + self.grant_access( + obj=self.test_document, permission=permission_metadata_add + ) + + response = self._request_document_multiple_metadata_add_get_view() + self.assertNotContains( + response, text=self.metadata_type.label, status_code=302 + ) + + def test_document_metadata_add_post_view_no_permission(self): + response = self._request_document_metadata_add_post_view() + self.assertEqual(response.status_code, 404) + + self.assertEqual(len(self.document.metadata.all()), 0) + + def test_document_metadata_add_post_view_with_full_access(self): + self.grant_access( + obj=self.test_document, permission=permission_metadata_add + ) + response = self._request_document_metadata_add_post_view() self.assertEqual(response.status_code, 302) self.assertEqual(len(self.document.metadata.all()), 1) - self.assertQuerysetEqual( qs=self.document.metadata.values('metadata_type',), values=[ @@ -86,13 +151,6 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): # Gitlab issue #204 # Problems to add required metadata after changing the document type - self.grant_access( - permission=permission_document_properties_edit, obj=self.document - ) - self.grant_access( - permission=permission_document_metadata_edit, obj=self.document - ) - document_type_2 = DocumentType.objects.create( label=TEST_DOCUMENT_TYPE_2_LABEL ) @@ -105,6 +163,12 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): metadata_type=metadata_type_2, required=True ) + self.grant_access( + obj=self.document, permission=permission_document_properties_edit + ) + self.grant_access( + obj=self.document, permission=permission_metadata_edit + ) self.document.set_document_type(document_type=document_type_2) response = self.get( @@ -133,13 +197,13 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): TEST_DOCUMENT_METADATA_VALUE_2 ) - def _request_get_document_document_metadata_remove_view(self): + def _request_document_document_metadata_remove_get_view(self): return self.get( viewname='metadata:document_metadata_remove', kwargs={'document_id': self.document.pk} ) - def _request_post_document_document_metadata_remove_view(self): + def _request_document_document_metadata_remove_post_view(self): return self.post( viewname='metadata:document_metadata_remove', kwargs={'document_id': self.document.pk}, data={ @@ -151,38 +215,24 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): } ) - def test_document_metadata_remove_view_no_permission(self): + def test_document_metadata_remove_get_view_no_permission(self): self.document_metadata = self.document.metadata.create( metadata_type=self.metadata_type, value='' ) - response = self._request_get_document_document_metadata_remove_view() + response = self._request_document_document_metadata_remove_get_view() self.assertNotContains( - response, text=self.metadata_type.label, status_code=200 + response=response, text=self.metadata_type.label, status_code=404 ) - response = self._request_post_document_document_metadata_remove_view() - self.assertEqual(response.status_code, 404) - - self.assertEqual(len(self.document.metadata.all()), 1) - - self.assertQuerysetEqual( - qs=self.document.metadata.values('metadata_type',), - values=[ - { - 'metadata_type': self.metadata_type.pk, - } - ], transform=dict - ) - - def test_document_metadata_remove_view_with_document_access(self): + def test_document_metadata_remove_get_view_with_full_access(self): self.document_metadata = self.document.metadata.create( metadata_type=self.metadata_type, value='' ) self.grant_access( - permission=permission_document_metadata_remove, obj=self.document + obj=self.document, permission=permission_metadata_remove, ) # Silence unrelated logging @@ -190,14 +240,32 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): level=logging.CRITICAL ) - response = self._request_get_document_document_metadata_remove_view() - + response = self._request_document_document_metadata_remove_get_view() self.assertContains( response, text=self.metadata_type.label, status_code=200 ) - response = self._request_post_document_document_metadata_remove_view() + def test_document_metadata_remove_post_view_no_permission(self): + self.document_metadata = self.document.metadata.create( + metadata_type=self.metadata_type, value='' + ) + response = self._request_document_document_metadata_remove_get_view() + self.assertNotContains( + response=response, text=self.metadata_type.label, status_code=404 + ) + + self.assertEqual(len(self.document.metadata.all()), 1) + + def test_document_metadata_remove_post_view_with_access(self): + self.document_metadata = self.document.metadata.create( + metadata_type=self.metadata_type, value='' + ) + + self.grant_access( + obj=self.test_document, permission=permission_metadata_remove + ) + response = self._request_document_document_metadata_remove_post_view() self.assertEqual(response.status_code, 302) self.assertEqual(len(self.document.metadata.all()), 0) @@ -227,10 +295,10 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): self.document_2 = self.upload_document() self.grant_access( - permission=permission_document_metadata_edit, obj=self.document + permission=permission_metadata_edit, obj=self.document ) self.grant_access( - permission=permission_document_metadata_edit, obj=self.document_2 + permission=permission_metadata_edit, obj=self.document_2 ) self.document_metadata = self.document.metadata.create( @@ -277,10 +345,10 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): def test_document_multiple_metadata_remove_with_access(self): self.document_2 = self.upload_document() self.grant_access( - permission=permission_document_metadata_remove, obj=self.document + permission=permission_metadata_remove, obj=self.document ) self.grant_access( - permission=permission_document_metadata_remove, obj=self.document_2 + permission=permission_metadata_remove, obj=self.document_2 ) self.document_metadata = self.document.metadata.create( @@ -311,10 +379,10 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): self.document_2 = self.upload_document() self.grant_access( - permission=permission_document_metadata_add, obj=self.document + permission=permission_metadata_add, obj=self.document ) self.grant_access( - permission=permission_document_metadata_add, obj=self.document_2 + permission=permission_metadata_add, obj=self.document_2 ) response = self._request_post_document_document_metadata_add_view() @@ -326,7 +394,7 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): def test_single_document_multiple_metadata_add_view_with_access(self): self.grant_access( - permission=permission_document_metadata_add, obj=self.document + permission=permission_metadata_add, obj=self.document ) metadata_type_2 = MetadataType.objects.create( name=TEST_METADATA_TYPE_NAME_2, label=TEST_METADATA_TYPE_LABEL_2 @@ -351,14 +419,10 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): ) -class MetadataTypeViewTestCase(DocumentTestMixin, MetadataTestsMixin, GenericViewTestCase): +class MetadataTypeViewViewTestCase(DocumentTestMixin, MetadataTestsMixin, GenericViewTestCase): auto_create_document_type = False auto_upload_document = False - def setUp(self): - super(MetadataTypeViewTestCase, self).setUp() - self.login_user() - def test_metadata_type_create_view_no_permission(self): response = self._request_metadata_type_create_view() diff --git a/mayan/apps/metadata/views.py b/mayan/apps/metadata/views.py index ca7846a875..ab5533b993 100644 --- a/mayan/apps/metadata/views.py +++ b/mayan/apps/metadata/views.py @@ -1,5 +1,7 @@ from __future__ import absolute_import, unicode_literals +from furl import furl + from django.conf import settings from django.contrib import messages from django.core.exceptions import ValidationError @@ -8,7 +10,6 @@ from django.shortcuts import get_object_or_404 from django.template import RequestContext from django.urls import reverse, reverse_lazy from django.utils.encoding import force_text -from django.utils.http import urlencode from django.utils.translation import ugettext_lazy as _, ungettext from mayan.apps.acls.models import AccessControlList @@ -16,6 +17,7 @@ from mayan.apps.common.generics import ( FormView, MultipleObjectFormActionView, SingleObjectCreateView, SingleObjectDeleteView, SingleObjectEditView, SingleObjectListView ) +from mayan.apps.common.mixins import ExternalObjectMixin from mayan.apps.documents.models import Document, DocumentType from mayan.apps.documents.permissions import ( permission_document_type_edit @@ -34,29 +36,20 @@ from .links import ( ) from .models import DocumentMetadata, MetadataType from .permissions import ( - permission_document_metadata_add, permission_document_metadata_edit, - permission_document_metadata_remove, permission_document_metadata_view, + permission_metadata_add, permission_metadata_edit, + permission_metadata_remove, permission_metadata_view, permission_metadata_type_create, permission_metadata_type_delete, permission_metadata_type_edit, permission_metadata_type_view ) -class DocumentMetadataAddView(MultipleObjectFormActionView): - form_class = DocumentMetadataAddForm - model = Document - object_permission = permission_document_metadata_add - pk_url_kwarg = 'document_id' - success_message = _('Metadata add request performed on %(count)d document') - success_message_plural = _( - 'Metadata add request performed on %(count)d documents' - ) - +class DocumentMetadataSameTypeMixin(object): def dispatch(self, request, *args, **kwargs): - result = super( - DocumentMetadataAddView, self - ).dispatch(request, *args, **kwargs) + result = super(DocumentMetadataSameTypeMixin, self).dispatch( + request, *args, **kwargs + ) - queryset = self.get_queryset() + queryset = self.get_object_list() for document in queryset: document.add_as_recent_document_for_user(request.user) @@ -71,40 +64,35 @@ class DocumentMetadataAddView(MultipleObjectFormActionView): return result - def form_valid(self, form): - result = super(DocumentMetadataAddView, self).form_valid(form=form) - queryset = self.get_queryset() +class DocumentMetadataAddView(DocumentMetadataSameTypeMixin, MultipleObjectFormActionView): + form_class = DocumentMetadataAddForm + model = Document + object_permission = permission_metadata_add + pk_url_kwarg = 'document_id' + success_message = _('Metadata add request performed on %(count)d document') + success_message_plural = _( + 'Metadata add request performed on %(count)d documents' + ) + def get_post_object_action_url(self): if self.action_count == 1: - return HttpResponseRedirect( - redirect_to=reverse( - viewname='metadata:document_metadata_edit', - kwargs={'document_id': queryset.first().pk} - ) - ) - elif self.action_count > 1: - return HttpResponseRedirect( - redirect_to='%s?%s' % ( - reverse( - viewname='metadata:document_multiple_metadata_edit' - ), urlencode( - { - 'id_list': ','.join( - map( - force_text, - queryset.values_list('pk', flat=True) - ) - ) - } - ) - ) + return reverse( + viewname='metadata:document_metadata_edit', + kwargs={'document_id': self.action_id_list[0]} ) - return result + elif self.action_count > 1: + url = furl( + path=reverse( + viewname='metadata:document_multiple_metadata_edit' + ), args={'id_list': self.action_id_list} + ) + + return url.tostr() def get_extra_context(self): - queryset = self.get_queryset() + queryset = self.get_object_list() result = { 'submit_label': _('Add'), @@ -128,7 +116,7 @@ class DocumentMetadataAddView(MultipleObjectFormActionView): return result def get_form_extra_kwargs(self): - queryset = self.get_queryset() + queryset = self.get_object_list() result = {} @@ -209,10 +197,10 @@ class DocumentMetadataAddView(MultipleObjectFormActionView): ) -class DocumentMetadataEditView(MultipleObjectFormActionView): +class DocumentMetadataEditView(DocumentMetadataSameTypeMixin, MultipleObjectFormActionView): form_class = DocumentMetadataFormSet model = Document - object_permission = permission_document_metadata_edit + object_permission = permission_metadata_edit pk_url_kwarg = 'document_id' success_message = _( 'Metadata edit request performed on %(count)d document' @@ -221,61 +209,8 @@ class DocumentMetadataEditView(MultipleObjectFormActionView): 'Metadata edit request performed on %(count)d documents' ) - def dispatch(self, request, *args, **kwargs): - result = super( - DocumentMetadataEditView, self - ).dispatch(request, *args, **kwargs) - - queryset = self.get_queryset() - - for document in queryset: - document.add_as_recent_document_for_user(request.user) - - if len(set([document.document_type.pk for document in queryset])) > 1: - messages.error( - message=_( - 'Selected documents must be of the same type.' - ), request=request - ) - return HttpResponseRedirect(redirect_to=self.previous_url) - - return result - - def form_valid(self, form): - result = super(DocumentMetadataEditView, self).form_valid(form=form) - - queryset = self.get_queryset() - - if self.action_count == 1: - return HttpResponseRedirect( - redirect_to=reverse( - viewname='metadata:document_metadata_edit', - kwargs={'document_id': queryset.first().pk} - ) - ) - elif self.action_count > 1: - return HttpResponseRedirect( - redirect_to='%s?%s' % ( - reverse( - viewname='metadata:document_multiple_metadata_edit' - ), urlencode( - { - 'id_list': ','.join( - map( - force_text, queryset.values_list( - 'pk', flat=True - ) - ) - ) - } - ) - ) - ) - - return result - def get_extra_context(self): - queryset = self.get_queryset() + queryset = self.get_object_list() id_list = ','.join( map( @@ -328,7 +263,7 @@ class DocumentMetadataEditView(MultipleObjectFormActionView): return result def get_initial(self): - queryset = self.get_queryset() + queryset = self.get_object_list() metadata_dict = {} initial = [] @@ -355,6 +290,22 @@ class DocumentMetadataEditView(MultipleObjectFormActionView): return initial + def get_post_object_action_url(self): + if self.action_count == 1: + return reverse( + viewname='metadata:document_metadata_edit', + kwargs={'document_id': self.action_id_list[0]} + ) + + elif self.action_count > 1: + url = furl( + path=reverse( + viewname='metadata:document_multiple_metadata_edit' + ), args={'id_list': self.action_id_list} + ) + + return url.tostr() + def object_action(self, form, instance): errors = [] for form in form.forms: @@ -393,25 +344,20 @@ class DocumentMetadataEditView(MultipleObjectFormActionView): ) -class DocumentMetadataListView(SingleObjectListView): - def get_document(self): - queryset = AccessControlList.objects.restrict_queryset( - permission=permission_document_metadata_view, - queryset=Document.objects.all(), - user=self.request.user - ) - - return get_object_or_404(klass=queryset, pk=self.kwargs['document_id']) +class DocumentMetadataListView(ExternalObjectMixin, SingleObjectListView): + external_object_class = Document + external_object_permission = permission_metadata_view + external_object_pk_url_kwarg = 'document_id' def get_extra_context(self): - document = self.get_document() + return { 'hide_object': True, - 'object': document, + 'object': self.external_object, 'no_results_icon': icon_metadata, 'no_results_main_link': link_document_metadata_add.resolve( context=RequestContext( - request=self.request, dict_={'object': document} + request=self.request, dict_={'object': self.external_object} ) ), 'no_results_text': _( @@ -421,17 +367,17 @@ class DocumentMetadataListView(SingleObjectListView): 'values.' ), 'no_results_title': _('This document doesn\'t have any metadata'), - 'title': _('Metadata for document: %s') % document, + 'title': _('Metadata for document: %s') % self.external_object, } - def get_object_list(self): - return self.get_document().metadata.all() + def get_source_queryset(self): + return self.external_object.metadata.all() -class DocumentMetadataRemoveView(MultipleObjectFormActionView): +class DocumentMetadataRemoveView(DocumentMetadataSameTypeMixin, MultipleObjectFormActionView): form_class = DocumentMetadataRemoveFormSet model = Document - object_permission = permission_document_metadata_remove + object_permission = permission_metadata_remove pk_url_kwarg = 'document_id' success_message = _( 'Metadata remove request performed on %(count)d document' @@ -440,60 +386,8 @@ class DocumentMetadataRemoveView(MultipleObjectFormActionView): 'Metadata remove request performed on %(count)d documents' ) - def dispatch(self, request, *args, **kwargs): - result = super( - DocumentMetadataRemoveView, self - ).dispatch(request, *args, **kwargs) - - queryset = self.get_queryset() - - for document in queryset: - document.add_as_recent_document_for_user(request.user) - - if len(set([document.document_type.pk for document in queryset])) > 1: - messages.error( - message=_( - 'Selected documents must be of the same type.' - ), request=request - ) - return HttpResponseRedirect(redirect_to=self.previous_url) - - return result - - def form_valid(self, form): - result = super(DocumentMetadataRemoveView, self).form_valid(form=form) - - queryset = self.get_queryset() - - if self.action_count == 1: - return HttpResponseRedirect( - redirect_to=reverse( - viewname='metadata:document_metadata_edit', - kwargs={'document_id': queryset.first().pk} - ) - ) - elif self.action_count > 1: - return HttpResponseRedirect( - redirect_to='%s?%s' % ( - reverse( - viewname='metadata:document_multiple_metadata_edit' - ), urlencode( - { - 'id_list': ','.join( - map( - force_text, - queryset.values_list('pk', flat=True) - ) - ) - } - ) - ) - ) - - return result - def get_extra_context(self): - queryset = self.get_queryset() + queryset = self.get_object_list() result = { 'form_display_mode_table': True, @@ -518,7 +412,7 @@ class DocumentMetadataRemoveView(MultipleObjectFormActionView): return result def get_initial(self): - queryset = self.get_queryset() + queryset = self.get_object_list() metadata = {} for document in queryset: @@ -545,6 +439,21 @@ class DocumentMetadataRemoveView(MultipleObjectFormActionView): ) return initial + def get_post_object_action_url(self): + if self.action_count == 1: + return reverse( + viewname='metadata:document_metadata_edit', + kwargs={'document_id': self.action_id_list[0]} + ) + elif self.action_count > 1: + url = furl( + path=reverse( + viewname='metadata:document_multiple_metadata_edit' + ), args={'id_list': self.action_id_list} + ) + + return url.tostr() + def object_action(self, form, instance): for form in form.forms: if form.cleaned_data['update']: @@ -651,15 +560,18 @@ class MetadataTypeListView(SingleObjectListView): 'title': _('Metadata types'), } - def get_object_list(self): + def get_source_queryset(self): return MetadataType.objects.all() -class SetupDocumentTypeMetadataTypes(FormView): +class SetupDocumentTypeMetadataTypes(ExternalObjectMixin, FormView): + external_object_class = DocumentType + external_object_permission = permission_metadata_type_edit + external_object_pk_url_kwarg = 'document_type_id' form_class = DocumentTypeMetadataTypeRelationshipFormSet main_model = 'document_type' - model = DocumentType submodel = MetadataType + submodel_permission = permission_metadata_type_edit def form_valid(self, form): try: @@ -693,10 +605,10 @@ class SetupDocumentTypeMetadataTypes(FormView): 'to this document type.' ), 'no_results_title': _('There are no metadata types available'), - 'object': self.get_object(), + 'object': self.external_object, 'title': _( 'Metadata types for document type: %s' - ) % self.get_object() + ) % self.external_object } def get_form_extra_kwargs(self): @@ -705,44 +617,36 @@ class SetupDocumentTypeMetadataTypes(FormView): } def get_initial(self): - obj = self.get_object() initial = [] - for element in self.get_queryset(): + for element in self.get_object_list(): initial.append( { - 'document_type': obj, + 'document_type': self.external_object, 'main_model': self.main_model, 'metadata_type': element, } ) return initial - def get_object(self): - queryset = AccessControlList.objects.restrict_queryset( - permission=permission_metadata_type_edit, - queryset=self.model.objects.all(), + def get_object_list(self): + return AccessControlList.objects.restrict_queryset( + permission=self.submodel_permission, + queryset=self.submodel._meta.default_manager.all(), user=self.request.user ) - return get_object_or_404( - klass=queryset, pk=self.kwargs['document_type_id'] - ) def get_post_action_redirect(self): return reverse(viewname='documents:document_type_list') - def get_queryset(self): - queryset = self.submodel.objects.all() - return AccessControlList.objects.restrict_queryset( - permission=permission_document_type_edit, - user=self.request.user, queryset=queryset - ) - class SetupMetadataTypesDocumentTypes(SetupDocumentTypeMetadataTypes): + external_object_class = MetadataType + external_object_permission = permission_metadata_type_edit + external_object_pk_url_kwarg = 'metadata_type_id' main_model = 'metadata_type' - model = MetadataType submodel = DocumentType + submodel_permission = permission_document_type_edit def get_extra_context(self): return { @@ -754,28 +658,17 @@ class SetupMetadataTypesDocumentTypes(SetupDocumentTypeMetadataTypes): } def get_initial(self): - obj = self.get_object() initial = [] - for element in self.get_queryset(): + for element in self.get_object_list(): initial.append( { 'document_type': element, 'main_model': self.main_model, - 'metadata_type': obj, + 'metadata_type': self.external_object, } ) return initial - def get_object(self): - queryset = AccessControlList.objects.restrict_queryset( - permission=permission_metadata_type_edit, - queryset=self.model.objects.all(), - user=self.request.user - ) - return get_object_or_404( - klass=queryset, pk=self.kwargs['metadata_type_id'] - ) - def get_post_action_redirect(self): return reverse(viewname='metadata:metadata_type_list')