Add DEFAULT_SCHEMA_CLASS setting (#5658)

* Add test for new setting

* Add DefaultSchema utility

* Add new setting to docs
This commit is contained in:
Carlton Gibson 2017-12-14 11:24:21 +01:00 committed by GitHub
parent 4a200d5e66
commit 791539acec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 41 additions and 3 deletions

View File

@ -94,6 +94,12 @@ A content negotiation class, that determines how a renderer is selected for the
Default: `'rest_framework.negotiation.DefaultContentNegotiation'` Default: `'rest_framework.negotiation.DefaultContentNegotiation'`
#### DEFAULT_SCHEMA_CLASS
A view inspector class that will be used for schema generation.
Default: `'rest_framework.schemas.AutoSchema'`
--- ---
## Generic view settings ## Generic view settings

View File

@ -23,7 +23,7 @@ Other access should target the submodules directly
from rest_framework.settings import api_settings from rest_framework.settings import api_settings
from .generators import SchemaGenerator from .generators import SchemaGenerator
from .inspectors import AutoSchema, ManualSchema # noqa from .inspectors import AutoSchema, DefaultSchema, ManualSchema # noqa
def get_schema_view( def get_schema_view(

View File

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
""" """
inspectors.py # Per-endpoint view introspection inspectors.py # Per-endpoint view introspection
@ -456,3 +457,13 @@ class ManualSchema(ViewInspector):
) )
return self._link return self._link
class DefaultSchema(object):
"""Allows overriding AutoSchema using DEFAULT_SCHEMA_CLASS setting"""
def __get__(self, instance, owner):
inspector_class = api_settings.DEFAULT_SCHEMA_CLASS
assert issubclass(inspector_class, ViewInspector), "DEFAULT_SCHEMA_CLASS must be set to a ViewInspector (usually an AutoSchema) subclass"
inspector = inspector_class()
inspector.view = instance
return inspector

View File

@ -55,6 +55,9 @@ DEFAULTS = {
'DEFAULT_PAGINATION_CLASS': None, 'DEFAULT_PAGINATION_CLASS': None,
'DEFAULT_FILTER_BACKENDS': (), 'DEFAULT_FILTER_BACKENDS': (),
# Schema
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.AutoSchema',
# Throttling # Throttling
'DEFAULT_THROTTLE_RATES': { 'DEFAULT_THROTTLE_RATES': {
'user': None, 'user': None,
@ -140,6 +143,7 @@ IMPORT_STRINGS = (
'DEFAULT_VERSIONING_CLASS', 'DEFAULT_VERSIONING_CLASS',
'DEFAULT_PAGINATION_CLASS', 'DEFAULT_PAGINATION_CLASS',
'DEFAULT_FILTER_BACKENDS', 'DEFAULT_FILTER_BACKENDS',
'DEFAULT_SCHEMA_CLASS',
'EXCEPTION_HANDLER', 'EXCEPTION_HANDLER',
'TEST_REQUEST_RENDERER_CLASSES', 'TEST_REQUEST_RENDERER_CLASSES',
'UNAUTHENTICATED_USER', 'UNAUTHENTICATED_USER',

View File

@ -18,7 +18,7 @@ from django.views.generic import View
from rest_framework import exceptions, status from rest_framework import exceptions, status
from rest_framework.request import Request from rest_framework.request import Request
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.schemas import AutoSchema from rest_framework.schemas import DefaultSchema
from rest_framework.settings import api_settings from rest_framework.settings import api_settings
from rest_framework.utils import formatting from rest_framework.utils import formatting
@ -117,7 +117,7 @@ class APIView(View):
# Allow dependency injection of other settings to make testing easier. # Allow dependency injection of other settings to make testing easier.
settings = api_settings settings = api_settings
schema = AutoSchema() schema = DefaultSchema()
@classmethod @classmethod
def as_view(cls, **initkwargs): def as_view(cls, **initkwargs):

View File

@ -516,6 +516,11 @@ class Test4605Regression(TestCase):
assert prefix == '/' assert prefix == '/'
class CustomViewInspector(AutoSchema):
"""A dummy AutoSchema subclass"""
pass
class TestAutoSchema(TestCase): class TestAutoSchema(TestCase):
def test_apiview_schema_descriptor(self): def test_apiview_schema_descriptor(self):
@ -523,6 +528,18 @@ class TestAutoSchema(TestCase):
assert hasattr(view, 'schema') assert hasattr(view, 'schema')
assert isinstance(view.schema, AutoSchema) assert isinstance(view.schema, AutoSchema)
def test_set_custom_inspector_class_on_view(self):
class CustomView(APIView):
schema = CustomViewInspector()
view = CustomView()
assert isinstance(view.schema, CustomViewInspector)
def test_set_custom_inspector_class_via_settings(self):
with override_settings(REST_FRAMEWORK={'DEFAULT_SCHEMA_CLASS': 'tests.test_schemas.CustomViewInspector'}):
view = APIView()
assert isinstance(view.schema, CustomViewInspector)
def test_get_link_requires_instance(self): def test_get_link_requires_instance(self):
descriptor = APIView.schema # Accessed from class descriptor = APIView.schema # Accessed from class
with pytest.raises(AssertionError): with pytest.raises(AssertionError):