Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 13311582ea | |||
| 9a89d8ccb0 | |||
| 16f67cd8c2 | |||
| 99fa7c25ca | |||
| 97e70d9d16 | |||
| ee086a6eec | |||
| 4af38c970a | |||
| 95337f85ad | |||
| 1352c2a23b | |||
| 8578b93eba | |||
| 212891b1b8 | |||
| ab6444a32e | |||
| 2e0f9a19a9 | |||
| cda808fe11 | |||
| e6219ab8b7 |
+3
-6
@@ -4,12 +4,13 @@ python:
|
|||||||
- '3.5'
|
- '3.5'
|
||||||
- '3.6'
|
- '3.6'
|
||||||
- '3.7'
|
- '3.7'
|
||||||
|
- '3.8-dev'
|
||||||
|
|
||||||
dist: xenial
|
dist: xenial
|
||||||
|
|
||||||
cache: pip
|
cache: pip
|
||||||
|
|
||||||
jobs:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- python: '3.6'
|
- python: '3.6'
|
||||||
env: TOXENV=docs
|
env: TOXENV=docs
|
||||||
@@ -38,6 +39,7 @@ jobs:
|
|||||||
allow_failures:
|
allow_failures:
|
||||||
- env: TOXENV=lint
|
- env: TOXENV=lint
|
||||||
- env: TOXENV=djmaster
|
- env: TOXENV=djmaster
|
||||||
|
- python: '3.8-dev'
|
||||||
|
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
|
||||||
@@ -59,11 +61,6 @@ after_success:
|
|||||||
codecov
|
codecov
|
||||||
fi
|
fi
|
||||||
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
- /^v?\d+\.\d+(\.\d+)?(-?\S+)?$/
|
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- test
|
- test
|
||||||
- name: publish
|
- name: publish
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
Contributing
|
Contributing
|
||||||
############
|
############
|
||||||
|
|
||||||
Contributions are always welcome and appreciated! Here are some ways you can contribut.
|
Contributions are always welcome and appreciated! Here are some ways you can contribute.
|
||||||
|
|
||||||
******
|
******
|
||||||
Issues
|
Issues
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ Generate **real** Swagger/OpenAPI 2.0 specifications from a Django Rest Framewor
|
|||||||
|
|
||||||
Compatible with
|
Compatible with
|
||||||
|
|
||||||
- **Django Rest Framework**: 3.8, 3.9
|
- **Django Rest Framework**: 3.8, 3.9, 3.10
|
||||||
- **Django**: 1.11, 2.1, 2.2
|
- **Django**: 1.11, 2.1, 2.2
|
||||||
- **Python**: 2.7, 3.5, 3.6, 3.7
|
- **Python**: 2.7, 3.5, 3.6, 3.7
|
||||||
|
|
||||||
|
|||||||
+12
-1
@@ -2,6 +2,17 @@
|
|||||||
Changelog
|
Changelog
|
||||||
#########
|
#########
|
||||||
|
|
||||||
|
**********
|
||||||
|
**1.17.0**
|
||||||
|
**********
|
||||||
|
|
||||||
|
*Release date: Oct 03, 2019*
|
||||||
|
|
||||||
|
- **ADDED:** added `JSONFieldInspector` for `JSONField` support (:pr:`417`)
|
||||||
|
- **IMPROVED:** updated ``swagger-ui`` to version 3.23.11
|
||||||
|
- **IMPROVED:** updated ``ReDoc`` to version 2.0.0-rc.14 (:issue:`398`)
|
||||||
|
- **FIXED:** fixed a type hint support issue (:pr:`428`, :issue:`450`)
|
||||||
|
- **FIXED:** fixed packaging issue caused by a missing requirement (:issue:`412`)
|
||||||
|
|
||||||
**********
|
**********
|
||||||
**1.16.1**
|
**1.16.1**
|
||||||
@@ -9,8 +20,8 @@ Changelog
|
|||||||
|
|
||||||
*Release date: Jul 16, 2019*
|
*Release date: Jul 16, 2019*
|
||||||
|
|
||||||
|
- **IMPROVED:** better enum type detection for nested `ChoiceField`\ s (:pr:`400`)
|
||||||
- **FIXED:** fixed DRF 3.10 compatibility (:pr:`408`, :issue:`410`, :issue:`411`)
|
- **FIXED:** fixed DRF 3.10 compatibility (:pr:`408`, :issue:`410`, :issue:`411`)
|
||||||
- **IMPROVED:** better enum type detection for nested `ChoiceField`s (:pr:`400`)
|
|
||||||
|
|
||||||
**********
|
**********
|
||||||
**1.16.0**
|
**1.16.0**
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ some properties of the generated :class:`.Operation`. For example, in a ``ViewSe
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
from drf_yasg.utils import swagger_auto_schema
|
||||||
|
|
||||||
@swagger_auto_schema(operation_description="partial_update description override", responses={404: 'slug not found'})
|
@swagger_auto_schema(operation_description="partial_update description override", responses={404: 'slug not found'})
|
||||||
def partial_update(self, request, *args, **kwargs):
|
def partial_update(self, request, *args, **kwargs):
|
||||||
"""partial_update method docstring"""
|
"""partial_update method docstring"""
|
||||||
@@ -376,7 +378,7 @@ A second example, of a :class:`~.inspectors.FieldInspector` that removes the ``t
|
|||||||
|
|
||||||
|
|
||||||
class AnotherSerializer(serializers.ModelSerializer):
|
class AnotherSerializer(serializers.ModelSerializer):
|
||||||
chilf = OneSerializer()
|
child = OneSerializer()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SomeParentModel
|
model = SomeParentModel
|
||||||
|
|||||||
+2
-1
@@ -85,6 +85,7 @@ to this list.
|
|||||||
:class:`'drf_yasg.inspectors.ChoiceFieldInspector' <.inspectors.ChoiceFieldInspector>`, |br| \
|
:class:`'drf_yasg.inspectors.ChoiceFieldInspector' <.inspectors.ChoiceFieldInspector>`, |br| \
|
||||||
:class:`'drf_yasg.inspectors.FileFieldInspector' <.inspectors.FileFieldInspector>`, |br| \
|
:class:`'drf_yasg.inspectors.FileFieldInspector' <.inspectors.FileFieldInspector>`, |br| \
|
||||||
:class:`'drf_yasg.inspectors.DictFieldInspector' <.inspectors.DictFieldInspector>`, |br| \
|
:class:`'drf_yasg.inspectors.DictFieldInspector' <.inspectors.DictFieldInspector>`, |br| \
|
||||||
|
:class:`'drf_yasg.inspectors.JSONFieldInspector' <.inspectors.JSONFieldInspector>`, |br| \
|
||||||
:class:`'drf_yasg.inspectors.HiddenFieldInspector' <.inspectors.HiddenFieldInspector>`, |br| \
|
:class:`'drf_yasg.inspectors.HiddenFieldInspector' <.inspectors.HiddenFieldInspector>`, |br| \
|
||||||
:class:`'drf_yasg.inspectors.RecursiveFieldInspector' <.inspectors.RecursiveFieldInspector>`, |br| \
|
:class:`'drf_yasg.inspectors.RecursiveFieldInspector' <.inspectors.RecursiveFieldInspector>`, |br| \
|
||||||
:class:`'drf_yasg.inspectors.SerializerMethodFieldInspector' <.inspectors.SerializerMethodFieldInspector>`, |br| \
|
:class:`'drf_yasg.inspectors.SerializerMethodFieldInspector' <.inspectors.SerializerMethodFieldInspector>`, |br| \
|
||||||
@@ -454,7 +455,7 @@ FETCH_SCHEMA_WITH_QUERY
|
|||||||
|
|
||||||
Fetch the OpenAPI document using the query parameters passed to the ReDoc page request.
|
Fetch the OpenAPI document using the query parameters passed to the ReDoc page request.
|
||||||
|
|
||||||
**Default**: :python:`'True` |br|
|
**Default**: :python:`True` |br|
|
||||||
*Maps to parameter*: -
|
*Maps to parameter*: -
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Generated
+260
-246
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "drf-yasg",
|
"name": "drf-yasg",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"redoc": "^2.0.0-rc.8-1",
|
"redoc": "^2.0.0-rc.14",
|
||||||
"swagger-ui-dist": "^3.22.3"
|
"swagger-ui-dist": "^3.23.11"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ ruamel.yaml>=0.15.34
|
|||||||
inflection>=0.3.1
|
inflection>=0.3.1
|
||||||
six>=1.10.0
|
six>=1.10.0
|
||||||
uritemplate>=3.0.0
|
uritemplate>=3.0.0
|
||||||
|
packaging
|
||||||
|
|
||||||
djangorestframework>=3.8
|
djangorestframework>=3.8
|
||||||
Django>=1.11.7
|
Django>=1.11.7
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# test project requirements
|
# test project requirements
|
||||||
Pillow>=4.3.0
|
Pillow>=4.3.0
|
||||||
django-cors-headers>=2.1.0
|
|
||||||
django-filter>=1.1.0,<2.0; python_version == "2.7"
|
django-filter>=1.1.0,<2.0; python_version == "2.7"
|
||||||
django-filter>=1.1.0; python_version >= "3.5"
|
django-filter>=1.1.0; python_version >= "3.5"
|
||||||
#djangorestframework-camel-case>=0.2.0
|
#djangorestframework-camel-case>=0.2.0
|
||||||
@@ -9,5 +8,3 @@ django-filter>=1.1.0; python_version >= "3.5"
|
|||||||
djangorestframework-recursive>=0.1.2
|
djangorestframework-recursive>=0.1.2
|
||||||
dj-database-url>=0.4.2
|
dj-database-url>=0.4.2
|
||||||
user_agents>=1.1.0
|
user_agents>=1.1.0
|
||||||
# django-oauth-toolkit 1.2 does not support Django 1.11
|
|
||||||
django-oauth-toolkit>=1.1.0,<1.2.0
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ SWAGGER_DEFAULTS = {
|
|||||||
'drf_yasg.inspectors.ChoiceFieldInspector',
|
'drf_yasg.inspectors.ChoiceFieldInspector',
|
||||||
'drf_yasg.inspectors.FileFieldInspector',
|
'drf_yasg.inspectors.FileFieldInspector',
|
||||||
'drf_yasg.inspectors.DictFieldInspector',
|
'drf_yasg.inspectors.DictFieldInspector',
|
||||||
|
'drf_yasg.inspectors.JSONFieldInspector',
|
||||||
'drf_yasg.inspectors.HiddenFieldInspector',
|
'drf_yasg.inspectors.HiddenFieldInspector',
|
||||||
'drf_yasg.inspectors.RelatedFieldInspector',
|
'drf_yasg.inspectors.RelatedFieldInspector',
|
||||||
'drf_yasg.inspectors.SerializerMethodFieldInspector',
|
'drf_yasg.inspectors.SerializerMethodFieldInspector',
|
||||||
|
|||||||
+10
-10
@@ -3,24 +3,16 @@ import logging
|
|||||||
import re
|
import re
|
||||||
from collections import OrderedDict, defaultdict
|
from collections import OrderedDict, defaultdict
|
||||||
|
|
||||||
import uritemplate
|
|
||||||
import rest_framework
|
import rest_framework
|
||||||
|
import uritemplate
|
||||||
from coreapi.compat import urlparse
|
from coreapi.compat import urlparse
|
||||||
|
from packaging.version import Version
|
||||||
from rest_framework import versioning
|
from rest_framework import versioning
|
||||||
from rest_framework.compat import URLPattern, URLResolver, get_original_route
|
from rest_framework.compat import URLPattern, URLResolver, get_original_route
|
||||||
from rest_framework.schemas.generators import EndpointEnumerator as _EndpointEnumerator
|
from rest_framework.schemas.generators import EndpointEnumerator as _EndpointEnumerator
|
||||||
from rest_framework.schemas.generators import endpoint_ordering, get_pk_name
|
from rest_framework.schemas.generators import endpoint_ordering, get_pk_name
|
||||||
|
|
||||||
from rest_framework.settings import api_settings
|
from rest_framework.settings import api_settings
|
||||||
|
|
||||||
from packaging.version import Version
|
|
||||||
if Version(rest_framework.__version__) < Version('3.10'):
|
|
||||||
from rest_framework.schemas.generators import SchemaGenerator
|
|
||||||
from rest_framework.schemas.inspectors import get_pk_description
|
|
||||||
else:
|
|
||||||
from rest_framework.schemas import SchemaGenerator
|
|
||||||
from rest_framework.schemas.utils import get_pk_description
|
|
||||||
|
|
||||||
from . import openapi
|
from . import openapi
|
||||||
from .app_settings import swagger_settings
|
from .app_settings import swagger_settings
|
||||||
from .errors import SwaggerGenerationError
|
from .errors import SwaggerGenerationError
|
||||||
@@ -28,6 +20,14 @@ from .inspectors.field import get_basic_type_info, get_queryset_field, get_query
|
|||||||
from .openapi import ReferenceResolver, SwaggerDict
|
from .openapi import ReferenceResolver, SwaggerDict
|
||||||
from .utils import force_real_str, get_consumes, get_produces
|
from .utils import force_real_str, get_consumes, get_produces
|
||||||
|
|
||||||
|
if Version(rest_framework.__version__) < Version('3.10'):
|
||||||
|
from rest_framework.schemas.generators import SchemaGenerator
|
||||||
|
from rest_framework.schemas.inspectors import get_pk_description
|
||||||
|
else:
|
||||||
|
from rest_framework.schemas import SchemaGenerator
|
||||||
|
from rest_framework.schemas.utils import get_pk_description
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
PATH_PARAMETER_RE = re.compile(r'{(?P<parameter>\w+)}')
|
PATH_PARAMETER_RE = re.compile(r'{(?P<parameter>\w+)}')
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ from .base import (
|
|||||||
)
|
)
|
||||||
from .field import (
|
from .field import (
|
||||||
CamelCaseJSONFilter, ChoiceFieldInspector, DictFieldInspector, FileFieldInspector, HiddenFieldInspector,
|
CamelCaseJSONFilter, ChoiceFieldInspector, DictFieldInspector, FileFieldInspector, HiddenFieldInspector,
|
||||||
InlineSerializerInspector, RecursiveFieldInspector, ReferencingSerializerInspector, RelatedFieldInspector,
|
InlineSerializerInspector, JSONFieldInspector, RecursiveFieldInspector, ReferencingSerializerInspector,
|
||||||
SerializerMethodFieldInspector, SimpleFieldInspector, StringDefaultFieldInspector
|
RelatedFieldInspector, SerializerMethodFieldInspector, SimpleFieldInspector, StringDefaultFieldInspector
|
||||||
)
|
)
|
||||||
from .query import CoreAPICompatInspector, DjangoRestResponsePagination
|
from .query import CoreAPICompatInspector, DjangoRestResponsePagination
|
||||||
from .view import SwaggerAutoSchema
|
from .view import SwaggerAutoSchema
|
||||||
@@ -24,7 +24,7 @@ __all__ = [
|
|||||||
|
|
||||||
# field inspectors
|
# field inspectors
|
||||||
'InlineSerializerInspector', 'RecursiveFieldInspector', 'ReferencingSerializerInspector', 'RelatedFieldInspector',
|
'InlineSerializerInspector', 'RecursiveFieldInspector', 'ReferencingSerializerInspector', 'RelatedFieldInspector',
|
||||||
'SimpleFieldInspector', 'FileFieldInspector', 'ChoiceFieldInspector', 'DictFieldInspector',
|
'SimpleFieldInspector', 'FileFieldInspector', 'ChoiceFieldInspector', 'DictFieldInspector', 'JSONFieldInspector',
|
||||||
'StringDefaultFieldInspector', 'CamelCaseJSONFilter', 'HiddenFieldInspector', 'SerializerMethodFieldInspector',
|
'StringDefaultFieldInspector', 'CamelCaseJSONFilter', 'HiddenFieldInspector', 'SerializerMethodFieldInspector',
|
||||||
|
|
||||||
# view inspectors
|
# view inspectors
|
||||||
|
|||||||
@@ -610,6 +610,8 @@ class SerializerMethodFieldInspector(FieldInspector):
|
|||||||
# look for Python 3.5+ style type hinting of the return value
|
# look for Python 3.5+ style type hinting of the return value
|
||||||
hint_class = inspect_signature(method).return_annotation
|
hint_class = inspect_signature(method).return_annotation
|
||||||
|
|
||||||
|
if not inspect.isclass(hint_class) and hasattr(hint_class, '__args__'):
|
||||||
|
hint_class = hint_class.__args__[0]
|
||||||
if inspect.isclass(hint_class) and not issubclass(hint_class, inspect._empty):
|
if inspect.isclass(hint_class) and not issubclass(hint_class, inspect._empty):
|
||||||
type_info = get_basic_type_info_from_hint(hint_class)
|
type_info = get_basic_type_info_from_hint(hint_class)
|
||||||
|
|
||||||
@@ -745,11 +747,23 @@ class HiddenFieldInspector(FieldInspector):
|
|||||||
return NotHandled
|
return NotHandled
|
||||||
|
|
||||||
|
|
||||||
|
class JSONFieldInspector(FieldInspector):
|
||||||
|
"""Provides conversion for ``JSONField``."""
|
||||||
|
|
||||||
|
def field_to_swagger_object(self, field, swagger_object_type, use_references, **kwargs):
|
||||||
|
SwaggerType, ChildSwaggerType = self._get_partial_types(field, swagger_object_type, use_references, **kwargs)
|
||||||
|
|
||||||
|
if isinstance(field, serializers.JSONField) and swagger_object_type == openapi.Schema:
|
||||||
|
return SwaggerType(type=openapi.TYPE_OBJECT)
|
||||||
|
|
||||||
|
return NotHandled
|
||||||
|
|
||||||
|
|
||||||
class StringDefaultFieldInspector(FieldInspector):
|
class StringDefaultFieldInspector(FieldInspector):
|
||||||
"""For otherwise unhandled fields, return them as plain :data:`.TYPE_STRING` objects."""
|
"""For otherwise unhandled fields, return them as plain :data:`.TYPE_STRING` objects."""
|
||||||
|
|
||||||
def field_to_swagger_object(self, field, swagger_object_type, use_references, **kwargs): # pragma: no cover
|
def field_to_swagger_object(self, field, swagger_object_type, use_references, **kwargs): # pragma: no cover
|
||||||
# TODO unhandled fields: TimeField JSONField
|
# TODO unhandled fields: TimeField
|
||||||
SwaggerType, ChildSwaggerType = self._get_partial_types(field, swagger_object_type, use_references, **kwargs)
|
SwaggerType, ChildSwaggerType = self._get_partial_types(field, swagger_object_type, use_references, **kwargs)
|
||||||
return SwaggerType(type=openapi.TYPE_STRING)
|
return SwaggerType(type=openapi.TYPE_STRING)
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import six
|
|||||||
|
|
||||||
from django.shortcuts import resolve_url
|
from django.shortcuts import resolve_url
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_str
|
||||||
from django.utils.functional import Promise
|
from django.utils.functional import Promise
|
||||||
from rest_framework.renderers import BaseRenderer, JSONRenderer, TemplateHTMLRenderer
|
from rest_framework.renderers import BaseRenderer, JSONRenderer, TemplateHTMLRenderer
|
||||||
from rest_framework.utils import encoders, json
|
from rest_framework.utils import encoders, json
|
||||||
@@ -124,7 +124,7 @@ class SwaggerUIRenderer(_UIRenderer):
|
|||||||
swagger_ui_settings = self.get_swagger_ui_settings()
|
swagger_ui_settings = self.get_swagger_ui_settings()
|
||||||
|
|
||||||
request = renderer_context.get('request', None)
|
request = renderer_context.get('request', None)
|
||||||
oauth_redirect_url = force_text(swagger_ui_settings.get('oauth2RedirectUrl', ''))
|
oauth_redirect_url = force_str(swagger_ui_settings.get('oauth2RedirectUrl', ''))
|
||||||
if request and oauth_redirect_url:
|
if request and oauth_redirect_url:
|
||||||
swagger_ui_settings['oauth2RedirectUrl'] = request.build_absolute_uri(oauth_redirect_url)
|
swagger_ui_settings['oauth2RedirectUrl'] = request.build_absolute_uri(oauth_redirect_url)
|
||||||
|
|
||||||
|
|||||||
+2
-2
File diff suppressed because one or more lines are too long
+41
-19
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -5,7 +5,7 @@ from collections import OrderedDict
|
|||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_str
|
||||||
from rest_framework import serializers, status
|
from rest_framework import serializers, status
|
||||||
from rest_framework.mixins import DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
|
from rest_framework.mixins import DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
|
||||||
from rest_framework.parsers import FileUploadParser
|
from rest_framework.parsers import FileUploadParser
|
||||||
@@ -434,7 +434,7 @@ def force_real_str(s, encoding='utf-8', strings_only=False, errors='strict'):
|
|||||||
Fix for https://github.com/axnsan12/drf-yasg/issues/159
|
Fix for https://github.com/axnsan12/drf-yasg/issues/159
|
||||||
"""
|
"""
|
||||||
if s is not None:
|
if s is not None:
|
||||||
s = force_text(s, encoding, strings_only, errors)
|
s = force_str(s, encoding, strings_only, errors)
|
||||||
if type(s) != str:
|
if type(s) != str:
|
||||||
s = '' + s
|
s = '' + s
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import warnings
|
import warnings
|
||||||
from functools import wraps
|
from functools import WRAPPER_ASSIGNMENTS, wraps
|
||||||
|
|
||||||
from django.utils.cache import add_never_cache_headers
|
from django.utils.cache import add_never_cache_headers
|
||||||
from django.utils.decorators import available_attrs
|
|
||||||
from django.views.decorators.cache import cache_page
|
from django.views.decorators.cache import cache_page
|
||||||
from django.views.decorators.vary import vary_on_headers
|
from django.views.decorators.vary import vary_on_headers
|
||||||
from rest_framework import exceptions
|
from rest_framework import exceptions
|
||||||
@@ -30,7 +29,7 @@ def deferred_never_cache(view_func):
|
|||||||
never be cached.
|
never be cached.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@wraps(view_func, assigned=available_attrs(view_func))
|
@wraps(view_func, assigned=WRAPPER_ASSIGNMENTS)
|
||||||
def _wrapped_view_func(request, *args, **kwargs):
|
def _wrapped_view_func(request, *args, **kwargs):
|
||||||
response = view_func(request, *args, **kwargs)
|
response = view_func(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
import rest_framework
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
|
import rest_framework
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from packaging.version import Version
|
from packaging.version import Version
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from snippets.models import LANGUAGE_CHOICES, STYLE_CHOICES, Snippet, SnippetViewer
|
||||||
|
|
||||||
if Version(rest_framework.__version__) < Version('3.10'):
|
if Version(rest_framework.__version__) < Version('3.10'):
|
||||||
from rest_framework.compat import MaxLengthValidator, MinValueValidator
|
from rest_framework.compat import MaxLengthValidator, MinValueValidator
|
||||||
else:
|
else:
|
||||||
from django.core.validators import MaxLengthValidator, MinValueValidator
|
from django.core.validators import MaxLengthValidator, MinValueValidator
|
||||||
from rest_framework import serializers
|
|
||||||
|
|
||||||
from snippets.models import LANGUAGE_CHOICES, STYLE_CHOICES, Snippet, SnippetViewer
|
|
||||||
|
|
||||||
|
|
||||||
class LanguageSerializer(serializers.Serializer):
|
class LanguageSerializer(serializers.Serializer):
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import json
|
import json
|
||||||
|
import sys
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@@ -17,6 +18,11 @@ from drf_yasg.errors import SwaggerGenerationError
|
|||||||
from drf_yasg.generators import OpenAPISchemaGenerator
|
from drf_yasg.generators import OpenAPISchemaGenerator
|
||||||
from drf_yasg.utils import swagger_auto_schema
|
from drf_yasg.utils import swagger_auto_schema
|
||||||
|
|
||||||
|
try:
|
||||||
|
import typing
|
||||||
|
except ImportError:
|
||||||
|
typing = None
|
||||||
|
|
||||||
|
|
||||||
def test_schema_is_valid(swagger, codec_yaml):
|
def test_schema_is_valid(swagger, codec_yaml):
|
||||||
codec_yaml.encode(swagger)
|
codec_yaml.encode(swagger)
|
||||||
@@ -273,3 +279,58 @@ def test_nested_choice_in_array_field(choices, field, expected_type):
|
|||||||
swagger = generator.get_schema(None, True)
|
swagger = generator.get_schema(None, True)
|
||||||
property_schema = swagger['definitions']['Array']['properties']['array']['items']
|
property_schema = swagger['definitions']['Array']['properties']['array']['items']
|
||||||
assert property_schema == openapi.Schema(title='Array', type=expected_type, enum=choices)
|
assert property_schema == openapi.Schema(title='Array', type=expected_type, enum=choices)
|
||||||
|
|
||||||
|
|
||||||
|
def test_json_field():
|
||||||
|
class TestJSONFieldSerializer(serializers.Serializer):
|
||||||
|
json = serializers.JSONField()
|
||||||
|
|
||||||
|
class JSONViewSet(viewsets.ModelViewSet):
|
||||||
|
serializer_class = TestJSONFieldSerializer
|
||||||
|
|
||||||
|
router = routers.DefaultRouter()
|
||||||
|
router.register(r'jsons', JSONViewSet, **_basename_or_base_name('jsons'))
|
||||||
|
|
||||||
|
generator = OpenAPISchemaGenerator(
|
||||||
|
info=openapi.Info(title='Test json field generator', default_version='v1'),
|
||||||
|
patterns=router.urls
|
||||||
|
)
|
||||||
|
|
||||||
|
swagger = generator.get_schema(None, True)
|
||||||
|
property_schema = swagger["definitions"]["TestJSONField"]["properties"]["json"]
|
||||||
|
assert property_schema == openapi.Schema(title='Json', type=openapi.TYPE_OBJECT)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('py_type, expected_type', [
|
||||||
|
(str, openapi.TYPE_STRING),
|
||||||
|
(int, openapi.TYPE_INTEGER),
|
||||||
|
(float, openapi.TYPE_NUMBER),
|
||||||
|
(bool, openapi.TYPE_BOOLEAN),
|
||||||
|
])
|
||||||
|
@pytest.mark.skipif(typing is None or sys.version_info.major < 3, reason="typing not supported")
|
||||||
|
def test_optional_return_type(py_type, expected_type):
|
||||||
|
|
||||||
|
class OptionalMethodSerializer(serializers.Serializer):
|
||||||
|
x = serializers.SerializerMethodField()
|
||||||
|
|
||||||
|
def get_x(self, instance):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Add the type annotation here in order to avoid a SyntaxError in py27
|
||||||
|
get_x.__annotations__["return"] = typing.Optional[py_type]
|
||||||
|
|
||||||
|
class OptionalMethodViewSet(viewsets.ViewSet):
|
||||||
|
@swagger_auto_schema(responses={200: openapi.Response("OK", OptionalMethodSerializer)})
|
||||||
|
def retrieve(self, request, pk=None):
|
||||||
|
return Response({'optional': None})
|
||||||
|
|
||||||
|
router = routers.DefaultRouter()
|
||||||
|
router.register(r'optional', OptionalMethodViewSet, **_basename_or_base_name('optional'))
|
||||||
|
|
||||||
|
generator = OpenAPISchemaGenerator(
|
||||||
|
info=openapi.Info(title='Test optional parameter', default_version='v1'),
|
||||||
|
patterns=router.urls
|
||||||
|
)
|
||||||
|
swagger = generator.get_schema(None, True)
|
||||||
|
property_schema = swagger["definitions"]["OptionalMethod"]["properties"]["x"]
|
||||||
|
assert property_schema == openapi.Schema(title='X', type=expected_type, readOnly=True)
|
||||||
|
|||||||
@@ -8,9 +8,10 @@ envlist =
|
|||||||
py27-django111-drf39-typing,
|
py27-django111-drf39-typing,
|
||||||
py27-django111-drf{38,39},
|
py27-django111-drf{38,39},
|
||||||
py{35,36}-django{111,21,22}-drf{38,39},
|
py{35,36}-django{111,21,22}-drf{38,39},
|
||||||
py37-django{21,22}-drf{38,39},
|
py37-django{21,22}-drf{38,39,310},
|
||||||
py37-django{21,22}-drf310,
|
py38-django22-drf310,
|
||||||
djmaster, lint, docs
|
djmaster, lint, docs
|
||||||
|
skip_missing_interpreters = true
|
||||||
|
|
||||||
[testenv:.package]
|
[testenv:.package]
|
||||||
# no additional dependencies besides PEP 517
|
# no additional dependencies besides PEP 517
|
||||||
@@ -19,8 +20,17 @@ deps =
|
|||||||
[testenv]
|
[testenv]
|
||||||
deps =
|
deps =
|
||||||
django111: Django>=1.11,<2.0
|
django111: Django>=1.11,<2.0
|
||||||
|
django111: django-cors-headers>=2.1.0
|
||||||
|
django111: django-oauth-toolkit>=1.1.0,<1.2.0
|
||||||
|
|
||||||
django21: Django>=2.1,<2.2
|
django21: Django>=2.1,<2.2
|
||||||
|
django21: django-cors-headers>=2.1.0
|
||||||
|
django21: django-oauth-toolkit>=1.2.0
|
||||||
|
|
||||||
django22: Django>=2.2,<2.3
|
django22: Django>=2.2,<2.3
|
||||||
|
django22: django-cors-headers>=2.1.0
|
||||||
|
django22: django-oauth-toolkit>=1.2.0
|
||||||
|
|
||||||
|
|
||||||
drf38: djangorestframework>=3.8,<3.9
|
drf38: djangorestframework>=3.8,<3.9
|
||||||
drf39: djangorestframework>=3.9,<3.10
|
drf39: djangorestframework>=3.9,<3.10
|
||||||
@@ -28,9 +38,12 @@ deps =
|
|||||||
|
|
||||||
typing: typing>=3.6.6
|
typing: typing>=3.6.6
|
||||||
|
|
||||||
# test with the latest build of django-rest-framework to get early warning of compatibility issues
|
# test with the latest builds of Django and django-rest-framework
|
||||||
djmaster: https://github.com/encode/django-rest-framework/archive/master.tar.gz
|
# to get early warning of compatibility issues
|
||||||
djmaster: https://github.com/django/django/archive/master.tar.gz
|
djmaster: https://github.com/django/django/archive/master.tar.gz
|
||||||
|
djmaster: https://github.com/ottoyiu/django-cors-headers/archive/master.tar.gz
|
||||||
|
djmaster: https://github.com/encode/django-rest-framework/archive/master.tar.gz
|
||||||
|
djmaster: django-oauth-toolkit>=1.2.0
|
||||||
|
|
||||||
# other dependencies
|
# other dependencies
|
||||||
-r requirements/validation.txt
|
-r requirements/validation.txt
|
||||||
@@ -77,5 +90,5 @@ known_standard_library =
|
|||||||
known_third_party =
|
known_third_party =
|
||||||
coreapi,coreschema,datadiff,dj_database_url,django,django_filters,djangorestframework_camel_case,
|
coreapi,coreschema,datadiff,dj_database_url,django,django_filters,djangorestframework_camel_case,
|
||||||
rest_framework_recursive,flex,gunicorn,inflection,pytest,rest_framework,ruamel,setuptools_scm,
|
rest_framework_recursive,flex,gunicorn,inflection,pytest,rest_framework,ruamel,setuptools_scm,
|
||||||
swagger_spec_validator,uritemplate,user_agents,whitenoise,oauth2_provider
|
swagger_spec_validator,uritemplate,user_agents,whitenoise,oauth2_provider,packaging
|
||||||
known_first_party = drf_yasg,testproj,articles,people,snippets,todo,users,urlconfs
|
known_first_party = drf_yasg,testproj,articles,people,snippets,todo,users,urlconfs
|
||||||
|
|||||||
Reference in New Issue
Block a user