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
|
* PyYAML
|
||||||
* django-autoadmin
|
* django-autoadmin
|
||||||
|
* djangorestframework-recursive
|
||||||
|
|
||||||
* Permissions refactor
|
* Permissions refactor
|
||||||
* ACLs 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.
|
* 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.
|
* Support to share an index as a FUSE filesystem.
|
||||||
* Preview images' titles are clickable.
|
* Preview images' titles are clickable.
|
||||||
|
* Improved API
|
||||||
|
|
||||||
Upgrading from a previous version
|
Upgrading from a previous version
|
||||||
=================================
|
=================================
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from rest_framework import generics
|
|||||||
from acls.models import AccessControlList
|
from acls.models import AccessControlList
|
||||||
from documents.models import Document
|
from documents.models import Document
|
||||||
from documents.permissions import permission_document_view
|
from documents.permissions import permission_document_view
|
||||||
|
from documents.serializers import DocumentSerializer
|
||||||
from permissions import Permission
|
from permissions import Permission
|
||||||
from rest_api.filters import MayanObjectPermissionsFilter
|
from rest_api.filters import MayanObjectPermissionsFilter
|
||||||
from rest_api.permissions import MayanPermission
|
from rest_api.permissions import MayanPermission
|
||||||
@@ -23,48 +24,64 @@ from .serializers import (
|
|||||||
|
|
||||||
|
|
||||||
class APIIndexListView(generics.ListCreateAPIView):
|
class APIIndexListView(generics.ListCreateAPIView):
|
||||||
serializer_class = IndexSerializer
|
|
||||||
queryset = Index.objects.all()
|
|
||||||
|
|
||||||
filter_backends = (MayanObjectPermissionsFilter,)
|
filter_backends = (MayanObjectPermissionsFilter,)
|
||||||
mayan_object_permissions = {'GET': [permission_document_indexing_view]}
|
mayan_object_permissions = {'GET': (permission_document_indexing_view,)}
|
||||||
mayan_view_permissions = {'POST': [permission_document_indexing_create]}
|
mayan_view_permissions = {'POST': (permission_document_indexing_create,)}
|
||||||
|
queryset = Index.objects.all()
|
||||||
|
serializer_class = IndexSerializer
|
||||||
|
|
||||||
def get(self, *args, **kwargs):
|
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)
|
return super(APIIndexListView, self).get(*args, **kwargs)
|
||||||
|
|
||||||
def post(self, *args, **kwargs):
|
def post(self, *args, **kwargs):
|
||||||
"""Create a new index."""
|
"""
|
||||||
|
Create a new index.
|
||||||
|
"""
|
||||||
|
|
||||||
return super(APIIndexListView, self).post(*args, **kwargs)
|
return super(APIIndexListView, self).post(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class APIIndexView(generics.RetrieveUpdateDestroyAPIView):
|
class APIIndexView(generics.RetrieveUpdateDestroyAPIView):
|
||||||
serializer_class = IndexSerializer
|
|
||||||
queryset = Index.objects.all()
|
|
||||||
|
|
||||||
permission_classes = (MayanPermission,)
|
|
||||||
mayan_object_permissions = {
|
mayan_object_permissions = {
|
||||||
'GET': [permission_document_indexing_view],
|
'GET': (permission_document_indexing_view,),
|
||||||
'PUT': [permission_document_indexing_edit],
|
'PUT': (permission_document_indexing_edit,),
|
||||||
'PATCH': [permission_document_indexing_edit],
|
'PATCH': (permission_document_indexing_edit,),
|
||||||
'DELETE': [permission_document_indexing_delete]
|
'DELETE': (permission_document_indexing_delete,)
|
||||||
}
|
}
|
||||||
|
permission_classes = (MayanPermission,)
|
||||||
|
queryset = Index.objects.all()
|
||||||
|
serializer_class = IndexSerializer
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
def delete(self, *args, **kwargs):
|
||||||
"""Delete the selected index."""
|
"""
|
||||||
|
Delete the selected index.
|
||||||
|
"""
|
||||||
|
|
||||||
return super(APIIndexView, self).delete(*args, **kwargs)
|
return super(APIIndexView, self).delete(*args, **kwargs)
|
||||||
|
|
||||||
def get(self, *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)
|
return super(APIIndexView, self).get(*args, **kwargs)
|
||||||
|
|
||||||
def patch(self, *args, **kwargs):
|
def patch(self, *args, **kwargs):
|
||||||
"""Partially edit an index."""
|
"""
|
||||||
|
Partially edit an index.
|
||||||
|
"""
|
||||||
|
|
||||||
return super(APIIndexView, self).patch(*args, **kwargs)
|
return super(APIIndexView, self).patch(*args, **kwargs)
|
||||||
|
|
||||||
def put(self, *args, **kwargs):
|
def put(self, *args, **kwargs):
|
||||||
"""Edit an index."""
|
"""
|
||||||
|
Edit an index.
|
||||||
|
"""
|
||||||
|
|
||||||
return super(APIIndexView, self).put(*args, **kwargs)
|
return super(APIIndexView, self).put(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@@ -75,11 +92,8 @@ class APIIndexNodeInstanceDocumentListView(generics.ListAPIView):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
filter_backends = (MayanObjectPermissionsFilter,)
|
filter_backends = (MayanObjectPermissionsFilter,)
|
||||||
mayan_object_permissions = {'GET': [permission_document_view]}
|
mayan_object_permissions = {'GET': (permission_document_view,)}
|
||||||
|
serializer_class = DocumentSerializer
|
||||||
def get_serializer_class(self):
|
|
||||||
from documents.serializers import DocumentSerializer
|
|
||||||
return DocumentSerializer
|
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
index_node_instance = get_object_or_404(
|
index_node_instance = get_object_or_404(
|
||||||
@@ -99,13 +113,15 @@ class APIIndexNodeInstanceDocumentListView(generics.ListAPIView):
|
|||||||
|
|
||||||
|
|
||||||
class APIIndexTemplateListView(generics.ListAPIView):
|
class APIIndexTemplateListView(generics.ListAPIView):
|
||||||
|
filter_backends = (MayanObjectPermissionsFilter,)
|
||||||
|
mayan_object_permissions = {'GET': (permission_document_indexing_view,)}
|
||||||
serializer_class = IndexTemplateNodeSerializer
|
serializer_class = IndexTemplateNodeSerializer
|
||||||
|
|
||||||
filter_backends = (MayanObjectPermissionsFilter,)
|
|
||||||
mayan_object_permissions = {'GET': [permission_document_indexing_view]}
|
|
||||||
|
|
||||||
def get(self, *args, **kwargs):
|
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)
|
return super(APIIndexTemplateListView, self).get(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@@ -115,26 +131,38 @@ class APIIndexTemplateView(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
|
|
||||||
permission_classes = (MayanPermission,)
|
permission_classes = (MayanPermission,)
|
||||||
mayan_object_permissions = {
|
mayan_object_permissions = {
|
||||||
'GET': [permission_document_indexing_view],
|
'GET': (permission_document_indexing_view,),
|
||||||
'PUT': [permission_document_indexing_edit],
|
'PUT': (permission_document_indexing_edit,),
|
||||||
'PATCH': [permission_document_indexing_edit],
|
'PATCH': (permission_document_indexing_edit,),
|
||||||
'DELETE': [permission_document_indexing_edit]
|
'DELETE': (permission_document_indexing_edit,)
|
||||||
}
|
}
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
def delete(self, *args, **kwargs):
|
||||||
"""Delete the selected index template node."""
|
"""
|
||||||
|
Delete the selected index template node.
|
||||||
|
"""
|
||||||
|
|
||||||
return super(APIIndexTemplateView, self).delete(*args, **kwargs)
|
return super(APIIndexTemplateView, self).delete(*args, **kwargs)
|
||||||
|
|
||||||
def get(self, *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)
|
return super(APIIndexTemplateView, self).get(*args, **kwargs)
|
||||||
|
|
||||||
def patch(self, *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)
|
return super(APIIndexTemplateView, self).patch(*args, **kwargs)
|
||||||
|
|
||||||
def put(self, *args, **kwargs):
|
def put(self, *args, **kwargs):
|
||||||
"""Edit an index template node."""
|
"""
|
||||||
|
Edit an index template node.
|
||||||
|
"""
|
||||||
|
|
||||||
return super(APIIndexTemplateView, self).put(*args, **kwargs)
|
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.
|
Returns a list of all the indexes to which a document belongs.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serializer_class = IndexInstanceNodeSerializer
|
|
||||||
|
|
||||||
filter_backends = (MayanObjectPermissionsFilter,)
|
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):
|
def get_queryset(self):
|
||||||
document = get_object_or_404(Document, pk=self.kwargs['pk'])
|
document = get_object_or_404(Document, pk=self.kwargs['pk'])
|
||||||
|
|||||||
@@ -1,40 +1,45 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
from rest_framework_recursive.fields import RecursiveField
|
||||||
|
|
||||||
from .models import Index, IndexInstanceNode, IndexTemplateNode
|
from .models import Index, IndexInstanceNode, IndexTemplateNode
|
||||||
|
|
||||||
|
|
||||||
class IndexInstanceNodeSerializer(serializers.ModelSerializer):
|
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:
|
class Meta:
|
||||||
fields = ('id', 'parent', 'value', 'level', 'documents', 'children')
|
fields = (
|
||||||
|
'documents', 'documents_count', 'children', 'id', 'level', 'parent',
|
||||||
|
'value'
|
||||||
|
)
|
||||||
model = IndexInstanceNode
|
model = IndexInstanceNode
|
||||||
|
|
||||||
def get_documents_count(self, obj):
|
def get_documents_count(self, instance):
|
||||||
return obj.documents.count()
|
return instance.documents.count()
|
||||||
|
|
||||||
|
|
||||||
IndexInstanceNodeSerializer.base_fields['children'] = IndexInstanceNodeSerializer(many=True)
|
|
||||||
|
|
||||||
|
|
||||||
class IndexTemplateNodeSerializer(serializers.ModelSerializer):
|
class IndexTemplateNodeSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
fields = (
|
fields = (
|
||||||
'id', 'parent', 'index', 'expression', 'enabled', 'link_documents',
|
'enabled', 'expression', 'id', 'index', 'level', 'link_documents',
|
||||||
'level'
|
'parent'
|
||||||
)
|
)
|
||||||
model = IndexTemplateNode
|
model = IndexTemplateNode
|
||||||
|
|
||||||
|
|
||||||
class IndexSerializer(serializers.ModelSerializer):
|
class IndexSerializer(serializers.ModelSerializer):
|
||||||
node_templates = IndexTemplateNodeSerializer(read_only=True, many=True)
|
|
||||||
instance_root = IndexInstanceNodeSerializer(read_only=True)
|
instance_root = IndexInstanceNodeSerializer(read_only=True)
|
||||||
|
node_templates = IndexTemplateNodeSerializer(read_only=True, many=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
fields = (
|
fields = (
|
||||||
'id', 'label', 'enabled', 'document_types', 'node_templates',
|
'document_types', 'enabled', 'id', 'instance_root', 'label',
|
||||||
'instance_root'
|
'node_templates',
|
||||||
)
|
)
|
||||||
model = Index
|
model = Index
|
||||||
|
|||||||
@@ -15,30 +15,81 @@ from .views import (
|
|||||||
|
|
||||||
urlpatterns = patterns(
|
urlpatterns = patterns(
|
||||||
'document_indexing.views',
|
'document_indexing.views',
|
||||||
url(r'^setup/index/list/$', SetupIndexListView.as_view(), name='index_setup_list'),
|
url(
|
||||||
url(r'^setup/index/create/$', SetupIndexCreateView.as_view(), name='index_setup_create'),
|
r'^setup/index/list/$', SetupIndexListView.as_view(),
|
||||||
url(r'^setup/index/(?P<pk>\d+)/edit/$', SetupIndexEditView.as_view(), name='index_setup_edit'),
|
name='index_setup_list'
|
||||||
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(
|
||||||
url(r'^setup/index/(?P<pk>\d+)/document_types/$', SetupIndexDocumentTypesView.as_view(), name='index_setup_document_types'),
|
r'^setup/index/create/$', SetupIndexCreateView.as_view(),
|
||||||
|
name='index_setup_create'
|
||||||
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(
|
||||||
url(r'^setup/template/node/(?P<node_pk>\d+)/delete/$', 'template_node_delete', name='template_node_delete'),
|
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'^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(
|
||||||
url(r'^list/for/document/(?P<document_id>\d+)/$', 'document_index_list', name='document_index_list'),
|
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(
|
api_urls = patterns(
|
||||||
'',
|
'',
|
||||||
url(r'^index/node/(?P<pk>[0-9]+)/documents/$', APIIndexNodeInstanceDocumentListView.as_view(), name='index-node-documents'),
|
url(
|
||||||
url(r'^index/template/(?P<pk>[0-9]+)/$', APIIndexTemplateView.as_view(), name='index-template-detail'),
|
r'^index/node/(?P<pk>[0-9]+)/documents/$',
|
||||||
url(r'^indexes/(?P<pk>[0-9]+)/$', APIIndexView.as_view(), name='index-detail'),
|
APIIndexNodeInstanceDocumentListView.as_view(),
|
||||||
url(r'^index/(?P<pk>[0-9]+)/template/$', APIIndexTemplateListView.as_view(), name='index-template-detail'),
|
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'^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-suit==0.2.13
|
||||||
django-widget-tweaks==1.3
|
django-widget-tweaks==1.3
|
||||||
djangorestframework==3.1.3
|
djangorestframework==3.1.3
|
||||||
|
djangorestframework-recursive==0.1.1
|
||||||
|
|
||||||
fusepy==2.0.2
|
fusepy==2.0.2
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user