Update API vies and serializers for the latest Django REST framework version. Replace DRF Swagger with DRF-YASG.

Signed-off-by: Michael Price <loneviking72@gmail.com>
This commit is contained in:
Michael Price
2018-03-04 04:29:04 -04:00
committed by Roberto Rosario
parent 77a3c103d1
commit 4378b28777
20 changed files with 298 additions and 194 deletions

View File

@@ -58,13 +58,15 @@ class APIObjectACLListView(generics.ListCreateAPIView):
"""
Extra context provided to the serializer class.
"""
return {
context = super(APIObjectACLListView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'content_object': self.get_content_object(),
'format': self.format_kwarg,
'request': self.request,
'view': self
}
)
return context
def get_serializer_class(self):
if self.request.method == 'GET':
@@ -173,12 +175,15 @@ class APIObjectACLPermissionListView(generics.ListCreateAPIView):
return WritableAccessControlListPermissionSerializer
def get_serializer_context(self):
return {
context = super(APIObjectACLPermissionListView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'acl': self.get_acl(),
'format': self.format_kwarg,
'request': self.request,
'view': self
}
)
return context
def post(self, *args, **kwargs):
"""
@@ -242,9 +247,12 @@ class APIObjectACLPermissionView(generics.RetrieveDestroyAPIView):
return self.get_acl().permissions.all()
def get_serializer_context(self):
return {
context = super(APIObjectACLPermissionView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'acl': self.get_acl(),
'format': self.format_kwarg,
'request': self.request,
'view': self
}
)
return context

View File

@@ -133,12 +133,15 @@ class APICabinetDocumentListView(generics.ListCreateAPIView):
"""
Extra context provided to the serializer class.
"""
return {
context = super(APICabinetDocumentListView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'cabinet': self.get_cabinet(),
'format': self.format_kwarg,
'request': self.request,
'view': self
}
)
return context
def get_cabinet(self):
return get_object_or_404(Cabinet, pk=self.kwargs['pk'])
@@ -198,12 +201,15 @@ class APICabinetDocumentView(generics.RetrieveDestroyAPIView):
"""
Extra context provided to the serializer class.
"""
return {
context = super(APICabinetDocumentView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'cabinet': self.get_cabinet(),
'format': self.format_kwarg,
'request': self.request,
'view': self
}
)
return context
def perform_destroy(self, instance):
self.get_cabinet().documents.remove(instance)

View File

@@ -31,9 +31,13 @@ class APICheckedoutDocumentListView(generics.ListCreateAPIView):
def get_queryset(self):
filtered_documents = AccessControlList.objects.filter_by_access(
(permission_document_view,), self.request.user,
permission=permission_document_view, user=self.request.user,
queryset=DocumentCheckout.objects.checked_out_documents()
)
filtered_documents = AccessControlList.objects.filter_by_access(
permission=permission_document_checkout_detail_view, user=self.request.user,
queryset=filtered_documents
)
return DocumentCheckout.objects.filter(
document__pk__in=filtered_documents.values_list('pk', flat=True)

View File

@@ -2,18 +2,16 @@ from __future__ import unicode_literals
from rest_framework import serializers
from documents.serializers import DocumentSerializer
from .models import DocumentCheckout
class DocumentCheckoutSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
# Hide this import otherwise strange circular import error occur
from documents.serializers import DocumentSerializer
super(DocumentCheckoutSerializer, self).__init__(*args, **kwargs)
self.fields['document'] = DocumentSerializer()
document = DocumentSerializer()
class Meta:
fields = ('document',)
model = DocumentCheckout

View File

@@ -55,12 +55,15 @@ class APICommentListView(generics.ListCreateAPIView):
"""
Extra context provided to the serializer class.
"""
return {
context = super(APICommentListView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'document': self.get_document(),
'format': self.format_kwarg,
'request': self.request,
'view': self
}
)
return context
def post(self, *args, **kwargs):
"""
@@ -108,13 +111,3 @@ class APICommentView(generics.RetrieveDestroyAPIView):
def get_queryset(self):
return self.get_document().comments.all()
def get_serializer_context(self):
"""
Extra context provided to the serializer class.
"""
return {
'format': self.format_kwarg,
'request': self.request,
'view': self
}

View File

@@ -83,13 +83,15 @@ class APIWorkflowDocumentTypeList(generics.ListCreateAPIView):
"""
Extra context provided to the serializer class.
"""
return {
'format': self.format_kwarg,
'request': self.request,
context = super(APIWorkflowDocumentTypeList, self).get_serializer_context()
if self.kwargs:
context.update(
{
'workflow': self.get_workflow(),
'view': self
}
)
return context
def get_workflow(self):
"""
@@ -152,12 +154,15 @@ class APIWorkflowDocumentTypeView(generics.RetrieveDestroyAPIView):
"""
Extra context provided to the serializer class.
"""
return {
'format': self.format_kwarg,
'request': self.request,
context = super(APIWorkflowDocumentTypeView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'workflow': self.get_workflow(),
'view': self
}
)
return context
def get_workflow(self):
"""
@@ -282,12 +287,15 @@ class APIWorkflowStateListView(generics.ListCreateAPIView):
"""
Extra context provided to the serializer class.
"""
return {
'format': self.format_kwarg,
'request': self.request,
context = super(APIWorkflowStateListView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'workflow': self.get_workflow(),
'view': self
}
)
return context
def get_workflow(self):
if self.request.method == 'GET':
@@ -336,12 +344,15 @@ class APIWorkflowStateView(generics.RetrieveUpdateDestroyAPIView):
"""
Extra context provided to the serializer class.
"""
return {
'format': self.format_kwarg,
'request': self.request,
context = super(APIWorkflowStateView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'workflow': self.get_workflow(),
'view': self
}
)
return context
def get_workflow(self):
if self.request.method == 'GET':
@@ -396,12 +407,15 @@ class APIWorkflowTransitionListView(generics.ListCreateAPIView):
"""
Extra context provided to the serializer class.
"""
return {
'format': self.format_kwarg,
'request': self.request,
context = super(APIWorkflowTransitionListView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'workflow': self.get_workflow(),
'view': self
}
)
return context
def get_workflow(self):
if self.request.method == 'GET':
@@ -455,12 +469,15 @@ class APIWorkflowTransitionView(generics.RetrieveUpdateDestroyAPIView):
"""
Extra context provided to the serializer class.
"""
return {
'format': self.format_kwarg,
'request': self.request,
context = super(APIWorkflowTransitionView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'workflow': self.get_workflow(),
'view': self
}
)
return context
def get_workflow(self):
if self.request.method == 'GET':
@@ -588,12 +605,15 @@ class APIWorkflowInstanceLogEntryListView(generics.ListCreateAPIView):
return WritableWorkflowInstanceLogEntrySerializer
def get_serializer_context(self):
return {
'format': self.format_kwarg,
'request': self.request,
context = super(APIWorkflowInstanceLogEntryListView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'workflow_instance': self.get_workflow_instance(),
'view': self
}
)
return context
def get_queryset(self):
return self.get_workflow_instance().log_entries.all()

View File

@@ -83,6 +83,9 @@ class APIDeletedDocumentView(generics.RetrieveDestroyAPIView):
class APIDeletedDocumentRestoreView(generics.GenericAPIView):
"""
Restore a trashed document.
---
POST:
omit_serializer: true
"""
mayan_object_permissions = {
@@ -91,6 +94,9 @@ class APIDeletedDocumentRestoreView(generics.GenericAPIView):
permission_classes = (MayanPermission,)
queryset = Document.trash.all()
def get_serializer(self, *args, **kwargs):
return None
def get_serializer_class(self):
return None
@@ -127,6 +133,9 @@ class APIDocumentDownloadView(DownloadMixin, generics.RetrieveAPIView):
def get_mimetype(self):
return self.get_object().latest_version.mimetype
def get_serializer(self, *args, **kwargs):
return None
def get_serializer_class(self):
return None
@@ -240,6 +249,9 @@ class APIDocumentVersionDownloadView(DownloadMixin, generics.RetrieveAPIView):
def get_mimetype(self):
return self.get_object().mimetype
def get_serializer(self, *args, **kwargs):
return None
def get_serializer_class(self):
return None
@@ -346,6 +358,9 @@ class APIDocumentPageImageView(generics.RetrieveAPIView):
def get_queryset(self):
return self.get_document_version().pages.all()
def get_serializer(self, *args, **kwargs):
return None
def get_serializer_class(self):
return None
@@ -574,6 +589,13 @@ class APIDocumentVersionsListView(generics.ListCreateAPIView):
mayan_permission_attribute_check = 'document'
permission_classes = (MayanPermission,)
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(status=status.HTTP_202_ACCEPTED, headers=headers)
def get_serializer_class(self):
if self.request.method == 'GET':
return DocumentVersionSerializer
@@ -601,13 +623,6 @@ class APIDocumentVersionsListView(generics.ListCreateAPIView):
APIDocumentVersionsListView, self
).post(request, *args, **kwargs)
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(status=status.HTTP_202_ACCEPTED, headers=headers)
class APIDocumentVersionView(generics.RetrieveUpdateDestroyAPIView):
"""

View File

@@ -46,6 +46,9 @@ class APISearchView(SearchModelMixin, generics.ListAPIView):
return queryset
def get_serializer(self, *args, **kwargs):
return None
class APIAdvancedSearchView(SearchModelMixin, generics.ListAPIView):
"""
@@ -89,6 +92,9 @@ class APIAdvancedSearchView(SearchModelMixin, generics.ListAPIView):
return queryset
def get_serializer(self, *args, **kwargs):
return None
class APISearchModelList(generics.ListAPIView):
serializer_class = SearchModelSerializer

View File

@@ -63,13 +63,16 @@ class APIResolvedSmartLinkDocumentListView(generics.ListAPIView):
"""
Extra context provided to the serializer class.
"""
return {
context = super(APIResolvedSmartLinkDocumentListView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'document': self.get_document(),
'format': self.format_kwarg,
'request': self.request,
'smart_link': self.get_smart_link(),
'view': self
}
)
return context
def get_queryset(self):
return self.get_smart_link().get_linked_document_for(
@@ -104,12 +107,15 @@ class APIResolvedSmartLinkView(generics.RetrieveAPIView):
"""
Extra context provided to the serializer class.
"""
return {
context = super(APIResolvedSmartLinkView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'document': self.get_document(),
'format': self.format_kwarg,
'request': self.request,
'view': self
}
)
return context
def get_queryset(self):
return SmartLink.objects.get_for(document=self.get_document())
@@ -141,12 +147,15 @@ class APIResolvedSmartLinkListView(generics.ListAPIView):
"""
Extra context provided to the serializer class.
"""
return {
context = super(APIResolvedSmartLinkListView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'document': self.get_document(),
'format': self.format_kwarg,
'request': self.request,
'view': self
}
)
return context
def get_queryset(self):
return SmartLink.objects.filter(
@@ -170,12 +179,15 @@ class APISmartLinkConditionListView(generics.ListCreateAPIView):
"""
Extra context provided to the serializer class.
"""
return {
'format': self.format_kwarg,
'request': self.request,
context = super(APISmartLinkConditionListView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'smart_link': self.get_smart_link(),
'view': self
}
)
return context
def get_smart_link(self):
if self.request.method == 'GET':
@@ -224,12 +236,15 @@ class APISmartLinkConditionView(generics.RetrieveUpdateDestroyAPIView):
"""
Extra context provided to the serializer class.
"""
return {
'format': self.format_kwarg,
'request': self.request,
context = super(APISmartLinkConditionView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'smart_link': self.get_smart_link(),
'view': self
}
)
return context
def get_smart_link(self):
if self.request.method == 'GET':

View File

@@ -65,13 +65,15 @@ class APIDocumentMetadataListView(generics.ListCreateAPIView):
"""
Extra context provided to the serializer class.
"""
return {
context = super(APIDocumentMetadataListView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'document': self.get_document(),
'format': self.format_kwarg,
'request': self.request,
'view': self
}
)
return context
def post(self, *args, **kwargs):
"""
@@ -249,13 +251,15 @@ class APIDocumentTypeMetadataTypeListView(generics.ListCreateAPIView):
"""
Extra context provided to the serializer class.
"""
return {
context = super(APIDocumentTypeMetadataTypeListView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'document_type': self.get_document_type(),
'format': self.format_kwarg,
'request': self.request,
'view': self
}
)
return context
def post(self, *args, **kwargs):
"""

View File

@@ -20,6 +20,9 @@ class APIDocumentOCRView(generics.GenericAPIView):
permission_classes = (MayanPermission,)
queryset = Document.objects.all()
def get_serializer(self, *args, **kwargs):
return None
def get_serializer_class(self):
return None
@@ -51,6 +54,9 @@ class APIDocumentVersionOCRView(generics.GenericAPIView):
def get_queryset(self):
return self.get_document().versions.all()
def get_serializer(self, *args, **kwargs):
return None
def get_serializer_class(self):
return None

View File

@@ -10,5 +10,5 @@ link_api = Link(
)
link_api_documentation = Link(
icon='fa fa-book', tags='new_window', text=_('API Documentation'),
view='django.swagger.base.view'
view='schema-swagger-ui'
)

View File

@@ -59,6 +59,9 @@ class APIStagingSourceFileImageView(generics.RetrieveAPIView):
type: number
"""
def get_serializer(self, *args, **kwargs):
return None
def get_serializer_class(self):
return None

View File

@@ -11,16 +11,9 @@ logger = logging.getLogger(__name__)
class StagingFolderFileSerializer(serializers.Serializer):
url = serializers.SerializerMethodField('get_url')
image_url = serializers.SerializerMethodField('get_image_url')
filename = serializers.CharField(max_length=255)
def get_url(self, obj):
return reverse(
'stagingfolderfile-detail',
args=(obj.staging_folder.pk, obj.encoded_filename,),
request=self.context.get('request')
)
image_url = serializers.SerializerMethodField()
url = serializers.SerializerMethodField()
def get_image_url(self, obj):
return reverse(
@@ -29,9 +22,20 @@ class StagingFolderFileSerializer(serializers.Serializer):
request=self.context.get('request')
)
def get_url(self, obj):
return reverse(
'stagingfolderfile-detail',
args=(obj.staging_folder.pk, obj.encoded_filename,),
request=self.context.get('request')
)
class StagingFolderSerializer(serializers.HyperlinkedModelSerializer):
files = serializers.SerializerMethodField('get_files')
files = serializers.SerializerMethodField()
class Meta:
fields = ('files',)
model = StagingFolderSource
def get_files(self, obj):
try:
@@ -42,9 +46,6 @@ class StagingFolderSerializer(serializers.HyperlinkedModelSerializer):
logger.error('unhandled exception: %s', exception)
return []
class Meta:
model = StagingFolderSource
class WebFormSourceSerializer(serializers.Serializer):
class Meta:

View File

@@ -153,12 +153,15 @@ class APIDocumentTagListView(generics.ListCreateAPIView):
"""
Extra context provided to the serializer class.
"""
return {
'format': self.format_kwarg,
'request': self.request,
context = super(APIDocumentTagListView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'document': self.get_document(),
'view': self
}
)
return context
def perform_create(self, serializer):
serializer.save(document=self.get_document())
@@ -213,12 +216,15 @@ class APIDocumentTagView(generics.RetrieveDestroyAPIView):
"""
Extra context provided to the serializer class.
"""
return {
'format': self.format_kwarg,
'request': self.request,
context = super(APIDocumentTagView, self).get_serializer_context()
if self.kwargs:
context.update(
{
'document': self.get_document(),
'view': self
}
)
return context
def perform_destroy(self, instance):
try:

View File

@@ -201,12 +201,15 @@ class APIUserGroupList(generics.ListCreateAPIView):
"""
Extra context provided to the serializer class.
"""
return {
'format': self.format_kwarg,
'request': self.request,
context = super(APIUserGroupList, self).get_serializer_context()
if self.kwargs:
context.update(
{
'user': self.get_user(),
'view': self
}
)
return context
def get_queryset(self):
user = self.get_user()

View File

@@ -105,7 +105,7 @@ INSTALLED_APPS = (
'tags',
'task_manager',
# Placed after rest_api to allow template overriding
'rest_framework_swagger',
'drf_yasg',
)
MIDDLEWARE_CLASSES = (
@@ -261,6 +261,7 @@ REST_FRAMEWORK = {
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10,
}
# --------- Pagination --------
@@ -283,20 +284,12 @@ CELERY_TIMEZONE = 'UTC'
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'
# ------------ CORS ------------
CORS_ORIGIN_ALLOW_ALL = True
# ------ Django REST Swagger -----
SWAGGER_SETTINGS = {
'api_version': '1',
'info': {
'title': _('Mayan EDMS API Documentation'),
'description': _('Free Open Source Document Management System.'),
'contact': 'roberto.rosario@mayan-edms.com',
'license': 'Apache 2.0',
'licenseUrl': 'http://www.apache.org/licenses/LICENSE-2.0.html'
}
}
# ------ Timezone --------
TIMEZONE_COOKIE_NAME = 'django_timezone'
TIMEZONE_SESSION_KEY = 'django_timezone'
# ----- Stronghold -------
STRONGHOLD_PUBLIC_URLS = (r'^/docs/.+$',)
# ----- Swagger --------
SWAGGER_SETTINGS = {
'DOC_EXPANSION': 'None',
}

View File

@@ -3,12 +3,32 @@ from __future__ import unicode_literals
from django.conf import settings
from django.conf.urls import include, url
from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from drf_yasg import openapi
from drf_yasg.views import get_schema_view
from rest_framework import permissions
import mayan
admin.autodiscover()
schema_view = get_schema_view(
openapi.Info(
title=_('%s API') % mayan.__title__,
default_version='v2',
description=mayan.__description__,
license=openapi.License(name=mayan.__license__),
),
validators=['flex', 'ssv'],
public=True,
permission_classes=(permissions.AllowAny,),
)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^docs/', include('rest_framework_swagger.urls')),
url(r'^swagger(?P<format>.json|.yaml)$', schema_view.without_ui(cache_timeout=None), name='schema-json'),
url(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=None), name='schema-swagger-ui'),
url(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=None), name='schema-redoc'),
]
if settings.DEBUG:

View File

@@ -1,4 +1,5 @@
# Packages to be remove during upgrades
django-filetransfers
django-rest-swagger
pytesseract
pdfminer

View File

@@ -17,13 +17,14 @@ django-mathfilters==0.4.0
django-model-utils==3.1.1
django-mptt==0.9.0
django-qsstats-magic==0.7.2
django-rest-swagger==0.3.10
django-stronghold==0.2.8
django-suit==0.2.25
django-widget-tweaks==1.4.1
djangorestframework==3.3.2
djangorestframework-recursive==0.1.1
djangorestframework==3.7.7
djangorestframework-recursive==0.1.2
drf-yasg==1.4.4
flex==6.12.0
furl==1.0.0
fusepy==2.0.4
@@ -42,3 +43,4 @@ pytz==2016.7
requests==2.18.4
sh==1.12.11
swagger-spec-validator==2.1.0