Improve document indexing API. Add django rest framework recursive to serialize index instance nodes.
This commit is contained in:
@@ -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
|
||||
=================================
|
||||
|
||||
@@ -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'])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<pk>\d+)/edit/$', SetupIndexEditView.as_view(), name='index_setup_edit'),
|
||||
url(r'^setup/index/(?P<pk>\d+)/delete/$', SetupIndexDeleteView.as_view(), name='index_setup_delete'),
|
||||
url(r'^setup/index/(?P<index_pk>\d+)/view/$', 'index_setup_view', name='index_setup_view'),
|
||||
url(r'^setup/index/(?P<pk>\d+)/document_types/$', SetupIndexDocumentTypesView.as_view(), name='index_setup_document_types'),
|
||||
|
||||
url(r'^setup/template/node/(?P<parent_pk>\d+)/create/child/$', 'template_node_create', name='template_node_create'),
|
||||
url(r'^setup/template/node/(?P<node_pk>\d+)/edit/$', 'template_node_edit', name='template_node_edit'),
|
||||
url(r'^setup/template/node/(?P<node_pk>\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<pk>\d+)/edit/$', SetupIndexEditView.as_view(),
|
||||
name='index_setup_edit'
|
||||
),
|
||||
url(
|
||||
r'^setup/index/(?P<pk>\d+)/delete/$', SetupIndexDeleteView.as_view(),
|
||||
name='index_setup_delete'
|
||||
),
|
||||
url(
|
||||
r'^setup/index/(?P<index_pk>\d+)/view/$', 'index_setup_view',
|
||||
name='index_setup_view'
|
||||
),
|
||||
url(
|
||||
r'^setup/index/(?P<pk>\d+)/document_types/$',
|
||||
SetupIndexDocumentTypesView.as_view(), name='index_setup_document_types'
|
||||
),
|
||||
url(
|
||||
r'^setup/template/node/(?P<parent_pk>\d+)/create/child/$',
|
||||
'template_node_create', name='template_node_create'
|
||||
),
|
||||
url(
|
||||
r'^setup/template/node/(?P<node_pk>\d+)/edit/$', 'template_node_edit',
|
||||
name='template_node_edit'
|
||||
),
|
||||
url(
|
||||
r'^setup/template/node/(?P<node_pk>\d+)/delete/$',
|
||||
'template_node_delete', name='template_node_delete'
|
||||
),
|
||||
|
||||
url(r'^index/list/$', IndexListView.as_view(), name='index_list'),
|
||||
url(r'^instance/node/(?P<pk>\d+)/$', IndexInstanceNodeView.as_view(), name='index_instance_node_view'),
|
||||
url(
|
||||
r'^instance/node/(?P<pk>\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<document_id>\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<document_id>\d+)/$', 'document_index_list',
|
||||
name='document_index_list'
|
||||
),
|
||||
)
|
||||
|
||||
api_urls = patterns(
|
||||
'',
|
||||
url(r'^index/node/(?P<pk>[0-9]+)/documents/$', APIIndexNodeInstanceDocumentListView.as_view(), name='index-node-documents'),
|
||||
url(r'^index/template/(?P<pk>[0-9]+)/$', APIIndexTemplateView.as_view(), name='index-template-detail'),
|
||||
url(r'^indexes/(?P<pk>[0-9]+)/$', APIIndexView.as_view(), name='index-detail'),
|
||||
url(r'^index/(?P<pk>[0-9]+)/template/$', APIIndexTemplateListView.as_view(), name='index-template-detail'),
|
||||
url(
|
||||
r'^index/node/(?P<pk>[0-9]+)/documents/$',
|
||||
APIIndexNodeInstanceDocumentListView.as_view(),
|
||||
name='index-node-documents'
|
||||
),
|
||||
url(
|
||||
r'^index/template/(?P<pk>[0-9]+)/$', APIIndexTemplateView.as_view(),
|
||||
name='index-template-detail'
|
||||
),
|
||||
url(
|
||||
r'^indexes/(?P<pk>[0-9]+)/$', APIIndexView.as_view(),
|
||||
name='index-detail'
|
||||
),
|
||||
url(
|
||||
r'^index/(?P<pk>[0-9]+)/template/$', APIIndexTemplateListView.as_view(),
|
||||
name='index-template-detail'
|
||||
),
|
||||
url(r'^indexes/$', APIIndexListView.as_view(), name='index-list'),
|
||||
url(r'^document/(?P<pk>[0-9]+)/indexes/$', APIDocumentIndexListView.as_view(), name='document-index-list'),
|
||||
url(
|
||||
r'^document/(?P<pk>[0-9]+)/indexes/$',
|
||||
APIDocumentIndexListView.as_view(), name='document-index-list'
|
||||
),
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user