Skip to content

Commit eb1d5e5

Browse files
committed
Add schema decorator for FBVs
1 parent d3620b1 commit eb1d5e5

File tree

3 files changed

+48
-1
lines changed

3 files changed

+48
-1
lines changed

docs/api-guide/views.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,28 @@ The available decorators are:
184184

185185
Each of these decorators takes a single argument which must be a list or tuple of classes.
186186

187+
188+
## View schema decorator
189+
190+
To override the default schema generation for function based views you may use
191+
the `@schema` decorator. This must come *after* (below) the `@api_view`
192+
decorator. For example:
193+
194+
from rest_framework.decorators import api_view, schema
195+
from rest_framework.schemas import AutoSchema
196+
197+
class CustomAutoSchema(AutoSchema):
198+
def get_link(*args):
199+
# override view introspection here...
200+
201+
@api_view(['GET'])
202+
@schema(CustomAutoSchema())
203+
def view(request):
204+
return Response({"message": "Hello for today! See you tomorrow!"})
205+
206+
This decorator takes a single `AutoSchema` instance, an `AutoSchema` subclass
207+
instance or `ManualSchema` instance as described in the [Schemas documentation][schemas],
208+
187209
[cite]: http://reinout.vanrees.org/weblog/2011/08/24/class-based-views-usage.html
188210
[cite2]: http://www.boredomandlaziness.org/2012/05/djangos-cbvs-are-not-mistake-but.html
189211
[settings]: settings.md

rest_framework/decorators.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ def handler(self, *args, **kwargs):
7272
WrappedAPIView.permission_classes = getattr(func, 'permission_classes',
7373
APIView.permission_classes)
7474

75+
WrappedAPIView.schema = getattr(func, 'schema',
76+
APIView.schema)
77+
7578
WrappedAPIView.exclude_from_schema = exclude_from_schema
7679
return WrappedAPIView.as_view()
7780
return decorator
@@ -112,6 +115,13 @@ def decorator(func):
112115
return decorator
113116

114117

118+
def schema(view_inspector):
119+
def decorator(func):
120+
func.schema = view_inspector
121+
return func
122+
return decorator
123+
124+
115125
def detail_route(methods=None, **kwargs):
116126
"""
117127
Used to mark a method on a ViewSet that should be routed for detail requests.

tests/test_decorators.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
from rest_framework.authentication import BasicAuthentication
77
from rest_framework.decorators import (
88
api_view, authentication_classes, parser_classes, permission_classes,
9-
renderer_classes, throttle_classes
9+
renderer_classes, schema, throttle_classes
1010
)
1111
from rest_framework.parsers import JSONParser
1212
from rest_framework.permissions import IsAuthenticated
1313
from rest_framework.renderers import JSONRenderer
1414
from rest_framework.response import Response
15+
from rest_framework.schemas import AutoSchema
1516
from rest_framework.test import APIRequestFactory
1617
from rest_framework.throttling import UserRateThrottle
1718
from rest_framework.views import APIView
@@ -151,3 +152,17 @@ def view(request):
151152

152153
response = view(request)
153154
assert response.status_code == status.HTTP_429_TOO_MANY_REQUESTS
155+
156+
def test_schema(self):
157+
"""
158+
Checks CustomSchema class is set on view
159+
"""
160+
class CustomSchema(AutoSchema):
161+
pass
162+
163+
@api_view(['GET'])
164+
@schema(CustomSchema())
165+
def view(request):
166+
return Response({})
167+
168+
assert isinstance(view.cls.schema, CustomSchema)

0 commit comments

Comments
 (0)