mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-28 00:49:49 +03:00
integer primary key, doc, cleanup, lint, test
This commit is contained in:
parent
1535ee2a3c
commit
d8c6821563
|
@ -14,16 +14,18 @@ from django.db import models
|
|||
from django.utils.encoding import force_str
|
||||
from django.utils.module_loading import import_string
|
||||
|
||||
from rest_framework import exceptions, renderers, serializers, permissions
|
||||
from rest_framework import exceptions, permissions, renderers, serializers
|
||||
from rest_framework.compat import uritemplate
|
||||
from rest_framework.fields import _UnvalidatedField, empty
|
||||
from rest_framework.schemas.openapi_utils import (
|
||||
TYPE_MAPPING, PolymorphicResponse
|
||||
)
|
||||
from rest_framework.settings import api_settings
|
||||
from rest_framework.schemas.openapi_utils import TYPE_MAPPING, PolymorphicResponse
|
||||
|
||||
from .generators import BaseSchemaGenerator
|
||||
from .inspectors import ViewInspector
|
||||
from .utils import get_pk_description, is_list_view
|
||||
|
||||
|
||||
AUTHENTICATION_SCHEMES = {
|
||||
cls.authentication_class: cls
|
||||
for cls in [import_string(cls) for cls in api_settings.SCHEMA_AUTHENTICATION_CLASSES]
|
||||
|
@ -180,7 +182,7 @@ class AutoSchema(ViewInspector):
|
|||
action_or_method = getattr(self.view, getattr(self.view, 'action', method.lower()), None)
|
||||
view_doc = inspect.getdoc(self.view) or ''
|
||||
action_doc = inspect.getdoc(action_or_method) or ''
|
||||
return view_doc + '\n\n' + action_doc if action_doc else view_doc
|
||||
return action_doc or view_doc
|
||||
|
||||
def get_auth(self, path, method):
|
||||
""" override this for custom behaviour """
|
||||
|
@ -262,8 +264,10 @@ class AutoSchema(ViewInspector):
|
|||
elif model_field is not None and model_field.primary_key:
|
||||
description = get_pk_description(model, model_field)
|
||||
|
||||
# TODO cover more cases
|
||||
if isinstance(model_field, models.UUIDField):
|
||||
# TODO are there more relevant PK base classes?
|
||||
if isinstance(model_field, models.IntegerField):
|
||||
schema = TYPE_MAPPING[int]
|
||||
elif isinstance(model_field, models.UUIDField):
|
||||
schema = TYPE_MAPPING[UUID]
|
||||
|
||||
parameter = {
|
||||
|
@ -498,7 +502,7 @@ class AutoSchema(ViewInspector):
|
|||
result = {
|
||||
'properties': properties
|
||||
}
|
||||
if required and method != 'PATCH' and not nested:
|
||||
if required and method != 'PATCH':
|
||||
result['required'] = required
|
||||
|
||||
return result
|
||||
|
@ -648,7 +652,6 @@ class AutoSchema(ViewInspector):
|
|||
}
|
||||
return {'200': self._get_response_for_code(path, method, schema)}
|
||||
|
||||
|
||||
def _get_response_for_code(self, path, method, serializer_instance):
|
||||
if not serializer_instance:
|
||||
return {'description': 'No response body'}
|
||||
|
@ -702,7 +705,7 @@ class AutoSchema(ViewInspector):
|
|||
|
||||
if name.endswith('Serializer'):
|
||||
name = name[:-10]
|
||||
if method == 'PATCH' and not nested:
|
||||
if method == 'PATCH' and not serializer.read_only: # TODO maybe even use serializer.partial
|
||||
name = 'Patched' + name
|
||||
|
||||
return name
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import inspect
|
||||
import warnings
|
||||
from datetime import date, datetime
|
||||
from decimal import Decimal
|
||||
from uuid import UUID
|
||||
from datetime import datetime, date
|
||||
|
||||
from rest_framework import authentication
|
||||
from rest_framework.settings import api_settings
|
||||
|
@ -103,6 +103,7 @@ def extend_schema(
|
|||
TODO some heavy explaining
|
||||
|
||||
:param operation:
|
||||
:param operation_id:
|
||||
:param extra_parameters:
|
||||
:param responses:
|
||||
:param request:
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
import pytest
|
||||
from django.conf.urls import url
|
||||
from django.db import models
|
||||
from django.test import RequestFactory, TestCase, override_settings
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from rest_framework import filters, generics, pagination, routers, serializers
|
||||
from rest_framework import (
|
||||
filters, generics, pagination, routers, serializers, viewsets
|
||||
)
|
||||
from rest_framework.compat import uritemplate
|
||||
from rest_framework.parsers import JSONParser, MultiPartParser
|
||||
from rest_framework.renderers import JSONRenderer
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.schemas.openapi import AutoSchema, SchemaGenerator, ComponentRegistry
|
||||
from rest_framework.schemas.openapi import (
|
||||
AutoSchema, ComponentRegistry, SchemaGenerator
|
||||
)
|
||||
|
||||
from . import views
|
||||
|
||||
|
@ -126,7 +131,7 @@ class TestOperationIntrospection(TestCase):
|
|||
operation = inspector.get_operation(path, method)
|
||||
assert operation == {
|
||||
'operationId': 'example_retrieve',
|
||||
'description': '\n\nA description of my GET operation.',
|
||||
'description': 'A description of my GET operation.',
|
||||
'parameters': [
|
||||
{
|
||||
'name': 'id',
|
||||
|
@ -294,8 +299,7 @@ class TestOperationIntrospection(TestCase):
|
|||
inspector = AutoSchema()
|
||||
inspector.view = view
|
||||
inspector.init(registry)
|
||||
|
||||
operation = inspector.get_operation(path, method)
|
||||
inspector.get_operation(path, method)
|
||||
example_schema = registry.schemas['Example']
|
||||
nested_schema = registry.schemas['Nested']
|
||||
|
||||
|
@ -681,6 +685,36 @@ class TestOperationIntrospection(TestCase):
|
|||
assert properties['ip']['type'] == 'string'
|
||||
assert 'format' not in properties['ip']
|
||||
|
||||
def test_modelviewset(self):
|
||||
class ExampleModel(models.Model):
|
||||
text = models.TextField()
|
||||
|
||||
class ExampleSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = ExampleModel
|
||||
fields = ['id', 'text']
|
||||
|
||||
class ExampleViewSet(viewsets.ModelViewSet):
|
||||
serializer_class = ExampleSerializer
|
||||
queryset = ExampleModel.objects.none()
|
||||
|
||||
from django.urls import path, include
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.register(r'example', ExampleViewSet)
|
||||
|
||||
generator = SchemaGenerator(patterns=[
|
||||
path(r'api/', include(router.urls))
|
||||
])
|
||||
generator._initialise_endpoints()
|
||||
|
||||
schema = generator.get_schema(request=None, public=True)
|
||||
|
||||
assert list(schema['paths']['/api/example/'].keys()) == ['get', 'post']
|
||||
assert list(schema['paths']['/api/example/{id}/'].keys()) == ['get', 'put', 'patch', 'delete']
|
||||
assert list(schema['components']['schemas'].keys()) == ['Example', 'PatchedExample']
|
||||
# TODO do more checks
|
||||
|
||||
|
||||
@pytest.mark.skipif(uritemplate is None, reason='uritemplate not installed.')
|
||||
@override_settings(REST_FRAMEWORK={'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.openapi.AutoSchema'})
|
||||
|
|
Loading…
Reference in New Issue
Block a user