diff --git a/docs/releases/2.0.rst b/docs/releases/2.0.rst index d7b7d9d03e..a2dbab348e 100644 --- a/docs/releases/2.0.rst +++ b/docs/releases/2.0.rst @@ -52,6 +52,7 @@ What's new in Mayan EDMS v2.0 * PyYAML * django-autoadmin + * djangorestframework-recursive * Permissions refactor * ACLs refactor @@ -75,6 +76,7 @@ What's new in Mayan EDMS v2.0 * Removal of eval from metadata type defaults and lookup fields. Django's own template language is now used instead. * Support to share an index as a FUSE filesystem. * Preview images' titles are clickable. +* Improved API Upgrading from a previous version ================================= diff --git a/mayan/apps/document_indexing/api_views.py b/mayan/apps/document_indexing/api_views.py index 0b6fdeeec2..5e41ff3144 100644 --- a/mayan/apps/document_indexing/api_views.py +++ b/mayan/apps/document_indexing/api_views.py @@ -8,6 +8,7 @@ from rest_framework import generics from acls.models import AccessControlList from documents.models import Document from documents.permissions import permission_document_view +from documents.serializers import DocumentSerializer from permissions import Permission from rest_api.filters import MayanObjectPermissionsFilter from rest_api.permissions import MayanPermission @@ -23,48 +24,64 @@ from .serializers import ( class APIIndexListView(generics.ListCreateAPIView): - serializer_class = IndexSerializer - queryset = Index.objects.all() - filter_backends = (MayanObjectPermissionsFilter,) - mayan_object_permissions = {'GET': [permission_document_indexing_view]} - mayan_view_permissions = {'POST': [permission_document_indexing_create]} + mayan_object_permissions = {'GET': (permission_document_indexing_view,)} + mayan_view_permissions = {'POST': (permission_document_indexing_create,)} + queryset = Index.objects.all() + serializer_class = IndexSerializer def get(self, *args, **kwargs): - """Returns a list of all the defined indexes.""" + """ + Returns a list of all the defined indexes. + """ + return super(APIIndexListView, self).get(*args, **kwargs) def post(self, *args, **kwargs): - """Create a new index.""" + """ + Create a new index. + """ + return super(APIIndexListView, self).post(*args, **kwargs) class APIIndexView(generics.RetrieveUpdateDestroyAPIView): - serializer_class = IndexSerializer - queryset = Index.objects.all() - - permission_classes = (MayanPermission,) mayan_object_permissions = { - 'GET': [permission_document_indexing_view], - 'PUT': [permission_document_indexing_edit], - 'PATCH': [permission_document_indexing_edit], - 'DELETE': [permission_document_indexing_delete] + 'GET': (permission_document_indexing_view,), + 'PUT': (permission_document_indexing_edit,), + 'PATCH': (permission_document_indexing_edit,), + 'DELETE': (permission_document_indexing_delete,) } + permission_classes = (MayanPermission,) + queryset = Index.objects.all() + serializer_class = IndexSerializer def delete(self, *args, **kwargs): - """Delete the selected index.""" + """ + Delete the selected index. + """ + return super(APIIndexView, self).delete(*args, **kwargs) def get(self, *args, **kwargs): - """Returns the details of the selected index.""" + """ + Returns the details of the selected index. + """ + return super(APIIndexView, self).get(*args, **kwargs) def patch(self, *args, **kwargs): - """Partially edit an index.""" + """ + Partially edit an index. + """ + return super(APIIndexView, self).patch(*args, **kwargs) def put(self, *args, **kwargs): - """Edit an index.""" + """ + Edit an index. + """ + return super(APIIndexView, self).put(*args, **kwargs) @@ -75,11 +92,8 @@ class APIIndexNodeInstanceDocumentListView(generics.ListAPIView): """ filter_backends = (MayanObjectPermissionsFilter,) - mayan_object_permissions = {'GET': [permission_document_view]} - - def get_serializer_class(self): - from documents.serializers import DocumentSerializer - return DocumentSerializer + mayan_object_permissions = {'GET': (permission_document_view,)} + serializer_class = DocumentSerializer def get_queryset(self): index_node_instance = get_object_or_404( @@ -99,13 +113,15 @@ class APIIndexNodeInstanceDocumentListView(generics.ListAPIView): class APIIndexTemplateListView(generics.ListAPIView): + filter_backends = (MayanObjectPermissionsFilter,) + mayan_object_permissions = {'GET': (permission_document_indexing_view,)} serializer_class = IndexTemplateNodeSerializer - filter_backends = (MayanObjectPermissionsFilter,) - mayan_object_permissions = {'GET': [permission_document_indexing_view]} - def get(self, *args, **kwargs): - """Returns a list of all the template nodes for the selected index.""" + """ + Returns a list of all the template nodes for the selected index. + """ + return super(APIIndexTemplateListView, self).get(*args, **kwargs) @@ -115,26 +131,38 @@ class APIIndexTemplateView(generics.RetrieveUpdateDestroyAPIView): permission_classes = (MayanPermission,) mayan_object_permissions = { - 'GET': [permission_document_indexing_view], - 'PUT': [permission_document_indexing_edit], - 'PATCH': [permission_document_indexing_edit], - 'DELETE': [permission_document_indexing_edit] + 'GET': (permission_document_indexing_view,), + 'PUT': (permission_document_indexing_edit,), + 'PATCH': (permission_document_indexing_edit,), + 'DELETE': (permission_document_indexing_edit,) } def delete(self, *args, **kwargs): - """Delete the selected index template node.""" + """ + Delete the selected index template node. + """ + return super(APIIndexTemplateView, self).delete(*args, **kwargs) def get(self, *args, **kwargs): - """Returns the details of the selected index template node.""" + """ + Returns the details of the selected index template node. + """ + return super(APIIndexTemplateView, self).get(*args, **kwargs) def patch(self, *args, **kwargs): - """Partially edit an index template node.""" + """ + Partially edit an index template node. + """ + return super(APIIndexTemplateView, self).patch(*args, **kwargs) def put(self, *args, **kwargs): - """Edit an index template node.""" + """ + Edit an index template node. + """ + return super(APIIndexTemplateView, self).put(*args, **kwargs) @@ -143,10 +171,9 @@ class APIDocumentIndexListView(generics.ListAPIView): Returns a list of all the indexes to which a document belongs. """ - serializer_class = IndexInstanceNodeSerializer - filter_backends = (MayanObjectPermissionsFilter,) - mayan_object_permissions = {'GET': [permission_document_indexing_view]} + mayan_object_permissions = {'GET': (permission_document_indexing_view,)} + serializer_class = IndexInstanceNodeSerializer def get_queryset(self): document = get_object_or_404(Document, pk=self.kwargs['pk']) diff --git a/mayan/apps/document_indexing/serializers.py b/mayan/apps/document_indexing/serializers.py index 7a6c784075..dc1c2b9b6a 100644 --- a/mayan/apps/document_indexing/serializers.py +++ b/mayan/apps/document_indexing/serializers.py @@ -1,40 +1,45 @@ from __future__ import unicode_literals from rest_framework import serializers +from rest_framework_recursive.fields import RecursiveField from .models import Index, IndexInstanceNode, IndexTemplateNode class IndexInstanceNodeSerializer(serializers.ModelSerializer): - documents = serializers.SerializerMethodField('get_documents_count') + children = serializers.ListField(child=RecursiveField()) + documents_count = serializers.SerializerMethodField() + documents = serializers.HyperlinkedIdentityField( + view_name='rest_api:index-node-documents' + ) class Meta: - fields = ('id', 'parent', 'value', 'level', 'documents', 'children') + fields = ( + 'documents', 'documents_count', 'children', 'id', 'level', 'parent', + 'value' + ) model = IndexInstanceNode - def get_documents_count(self, obj): - return obj.documents.count() - - -IndexInstanceNodeSerializer.base_fields['children'] = IndexInstanceNodeSerializer(many=True) + def get_documents_count(self, instance): + return instance.documents.count() class IndexTemplateNodeSerializer(serializers.ModelSerializer): class Meta: fields = ( - 'id', 'parent', 'index', 'expression', 'enabled', 'link_documents', - 'level' + 'enabled', 'expression', 'id', 'index', 'level', 'link_documents', + 'parent' ) model = IndexTemplateNode class IndexSerializer(serializers.ModelSerializer): - node_templates = IndexTemplateNodeSerializer(read_only=True, many=True) instance_root = IndexInstanceNodeSerializer(read_only=True) + node_templates = IndexTemplateNodeSerializer(read_only=True, many=True) class Meta: fields = ( - 'id', 'label', 'enabled', 'document_types', 'node_templates', - 'instance_root' + 'document_types', 'enabled', 'id', 'instance_root', 'label', + 'node_templates', ) model = Index diff --git a/mayan/apps/document_indexing/urls.py b/mayan/apps/document_indexing/urls.py index 1dd7fff840..a09af91b28 100644 --- a/mayan/apps/document_indexing/urls.py +++ b/mayan/apps/document_indexing/urls.py @@ -15,30 +15,81 @@ from .views import ( urlpatterns = patterns( 'document_indexing.views', - url(r'^setup/index/list/$', SetupIndexListView.as_view(), name='index_setup_list'), - url(r'^setup/index/create/$', SetupIndexCreateView.as_view(), name='index_setup_create'), - url(r'^setup/index/(?P\d+)/edit/$', SetupIndexEditView.as_view(), name='index_setup_edit'), - url(r'^setup/index/(?P\d+)/delete/$', SetupIndexDeleteView.as_view(), name='index_setup_delete'), - url(r'^setup/index/(?P\d+)/view/$', 'index_setup_view', name='index_setup_view'), - url(r'^setup/index/(?P\d+)/document_types/$', SetupIndexDocumentTypesView.as_view(), name='index_setup_document_types'), - - url(r'^setup/template/node/(?P\d+)/create/child/$', 'template_node_create', name='template_node_create'), - url(r'^setup/template/node/(?P\d+)/edit/$', 'template_node_edit', name='template_node_edit'), - url(r'^setup/template/node/(?P\d+)/delete/$', 'template_node_delete', name='template_node_delete'), + url( + r'^setup/index/list/$', SetupIndexListView.as_view(), + name='index_setup_list' + ), + url( + r'^setup/index/create/$', SetupIndexCreateView.as_view(), + name='index_setup_create' + ), + url( + r'^setup/index/(?P\d+)/edit/$', SetupIndexEditView.as_view(), + name='index_setup_edit' + ), + url( + r'^setup/index/(?P\d+)/delete/$', SetupIndexDeleteView.as_view(), + name='index_setup_delete' + ), + url( + r'^setup/index/(?P\d+)/view/$', 'index_setup_view', + name='index_setup_view' + ), + url( + r'^setup/index/(?P\d+)/document_types/$', + SetupIndexDocumentTypesView.as_view(), name='index_setup_document_types' + ), + url( + r'^setup/template/node/(?P\d+)/create/child/$', + 'template_node_create', name='template_node_create' + ), + url( + r'^setup/template/node/(?P\d+)/edit/$', 'template_node_edit', + name='template_node_edit' + ), + url( + r'^setup/template/node/(?P\d+)/delete/$', + 'template_node_delete', name='template_node_delete' + ), url(r'^index/list/$', IndexListView.as_view(), name='index_list'), - url(r'^instance/node/(?P\d+)/$', IndexInstanceNodeView.as_view(), name='index_instance_node_view'), + url( + r'^instance/node/(?P\d+)/$', IndexInstanceNodeView.as_view(), + name='index_instance_node_view' + ), - url(r'^rebuild/all/$', 'rebuild_index_instances', name='rebuild_index_instances'), - url(r'^list/for/document/(?P\d+)/$', 'document_index_list', name='document_index_list'), + url( + r'^rebuild/all/$', 'rebuild_index_instances', + name='rebuild_index_instances' + ), + url( + r'^list/for/document/(?P\d+)/$', 'document_index_list', + name='document_index_list' + ), ) api_urls = patterns( '', - url(r'^index/node/(?P[0-9]+)/documents/$', APIIndexNodeInstanceDocumentListView.as_view(), name='index-node-documents'), - url(r'^index/template/(?P[0-9]+)/$', APIIndexTemplateView.as_view(), name='index-template-detail'), - url(r'^indexes/(?P[0-9]+)/$', APIIndexView.as_view(), name='index-detail'), - url(r'^index/(?P[0-9]+)/template/$', APIIndexTemplateListView.as_view(), name='index-template-detail'), + url( + r'^index/node/(?P[0-9]+)/documents/$', + APIIndexNodeInstanceDocumentListView.as_view(), + name='index-node-documents' + ), + url( + r'^index/template/(?P[0-9]+)/$', APIIndexTemplateView.as_view(), + name='index-template-detail' + ), + url( + r'^indexes/(?P[0-9]+)/$', APIIndexView.as_view(), + name='index-detail' + ), + url( + r'^index/(?P[0-9]+)/template/$', APIIndexTemplateListView.as_view(), + name='index-template-detail' + ), url(r'^indexes/$', APIIndexListView.as_view(), name='index-list'), - url(r'^document/(?P[0-9]+)/indexes/$', APIDocumentIndexListView.as_view(), name='document-index-list'), + url( + r'^document/(?P[0-9]+)/indexes/$', + APIDocumentIndexListView.as_view(), name='document-index-list' + ), ) diff --git a/requirements/common.txt b/requirements/common.txt index da6ba4b270..31790f6096 100644 --- a/requirements/common.txt +++ b/requirements/common.txt @@ -20,6 +20,7 @@ django-rest-swagger==0.3.3 django-suit==0.2.13 django-widget-tweaks==1.3 djangorestframework==3.1.3 +djangorestframework-recursive==0.1.1 fusepy==2.0.2