diff --git a/cvat-ui/.gitignore b/cvat-ui/.gitignore index 841dae58..4952a5fa 100644 --- a/cvat-ui/.gitignore +++ b/cvat-ui/.gitignore @@ -2,4 +2,6 @@ /node_modules /dist +/build +/yarn.lock diff --git a/cvat/apps/engine/serializers.py b/cvat/apps/engine/serializers.py index 9ef3556d..08903d7e 100644 --- a/cvat/apps/engine/serializers.py +++ b/cvat/apps/engine/serializers.py @@ -26,8 +26,12 @@ class AttributeSerializer(serializers.ModelSerializer): return attribute def to_representation(self, instance): - attribute = super().to_representation(instance) - attribute['values'] = attribute['values'].split('\n') + if instance: + attribute = super().to_representation(instance) + attribute['values'] = attribute['values'].split('\n') + else: + attribute = instance + return attribute class LabelSerializer(serializers.ModelSerializer): @@ -75,8 +79,11 @@ class ClientFileSerializer(serializers.ModelSerializer): # pylint: disable=no-self-use def to_representation(self, instance): - upload_dir = instance.task.get_upload_dirname() - return instance.file.path[len(upload_dir) + 1:] + if instance: + upload_dir = instance.task.get_upload_dirname() + return instance.file.path[len(upload_dir) + 1:] + else: + return instance class ServerFileSerializer(serializers.ModelSerializer): class Meta: @@ -89,7 +96,7 @@ class ServerFileSerializer(serializers.ModelSerializer): # pylint: disable=no-self-use def to_representation(self, instance): - return instance.file + return instance.file if instance else instance class RemoteFileSerializer(serializers.ModelSerializer): class Meta: @@ -102,7 +109,7 @@ class RemoteFileSerializer(serializers.ModelSerializer): # pylint: disable=no-self-use def to_representation(self, instance): - return instance.file + return instance.file if instance else instance class RqStatusSerializer(serializers.Serializer): state = serializers.ChoiceField(choices=[ diff --git a/cvat/apps/engine/urls.py b/cvat/apps/engine/urls.py index 6631874b..eef0ab2e 100644 --- a/cvat/apps/engine/urls.py +++ b/cvat/apps/engine/urls.py @@ -37,9 +37,12 @@ urlpatterns = [ path('dashboard/', views.dispatch_request), # documentation for API - path('api/swagger.$', schema_view.without_ui(cache_timeout=0), name='schema-json'), - path('api/swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), - path('api/docs/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'), + path('api/swagger', views.wrap_swagger( + schema_view.without_ui(cache_timeout=0)), name='schema-json'), + path('api/swagger/', views.wrap_swagger( + schema_view.with_ui('swagger', cache_timeout=0)), name='schema-swagger-ui'), + path('api/docs/', views.wrap_swagger( + schema_view.with_ui('redoc', cache_timeout=0)), name='schema-redoc'), # entry point for API path('api/v1/auth/', include('cvat.apps.authentication.api_urls')), diff --git a/cvat/apps/engine/views.py b/cvat/apps/engine/views.py index b6ad69d6..c4e81647 100644 --- a/cvat/apps/engine/views.py +++ b/cvat/apps/engine/views.py @@ -55,6 +55,22 @@ from django.utils.decorators import method_decorator from drf_yasg.inspectors import NotHandled, CoreAPICompatInspector from django_filters.rest_framework import DjangoFilterBackend +# drf-yasg component doesn't handle correctly URL_FORMAT_OVERRIDE and +# send requests with ?format=openapi suffix instead of ?scheme=openapi. +# We map the required paramater explicitly and add it into query arguments +# on the server side. +def wrap_swagger(view): + @login_required + def _map_format_to_schema(request, scheme=None): + if 'format' in request.GET: + request.GET = request.GET.copy() + format_alias = settings.REST_FRAMEWORK['URL_FORMAT_OVERRIDE'] + request.GET[format_alias] = request.GET['format'] + + return view(request, format=scheme) + + return _map_format_to_schema + # Server REST API @login_required def dispatch_request(request): diff --git a/cvat/requirements/base.txt b/cvat/requirements/base.txt index 5fe31b00..7b688b34 100644 --- a/cvat/requirements/base.txt +++ b/cvat/requirements/base.txt @@ -30,9 +30,9 @@ GitPython==2.1.11 coreapi==2.3.3 django-filter==2.0.0 Markdown==3.0.1 -djangorestframework==3.9.1 +djangorestframework==3.9.3 Pygments==2.3.1 -drf-yasg==1.16.0 +drf-yasg==1.17.0 Shapely==1.6.4.post2 pdf2image==1.6.0 pascal_voc_writer==0.1.4 diff --git a/cvat/settings/base.py b/cvat/settings/base.py index 961c792f..08ae7e2b 100644 --- a/cvat/settings/base.py +++ b/cvat/settings/base.py @@ -145,7 +145,7 @@ REST_FRAMEWORK = { 'rest_framework.filters.OrderingFilter'), # Disable default handling of the 'format' query parameter by REST framework - 'URL_FORMAT_OVERRIDE': None, + 'URL_FORMAT_OVERRIDE': 'scheme', } REST_AUTH_REGISTER_SERIALIZERS = {