Skip to content

Commit 609f708

Browse files
authored
Fix schema generation for ObtainAuthToken view. (#7211)
1 parent 8aa8be7 commit 609f708

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

rest_framework/authtoken/serializers.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,19 @@
55

66

77
class AuthTokenSerializer(serializers.Serializer):
8-
username = serializers.CharField(label=_("Username"))
8+
username = serializers.CharField(
9+
label=_("Username"),
10+
write_only=True
11+
)
912
password = serializers.CharField(
1013
label=_("Password"),
1114
style={'input_type': 'password'},
12-
trim_whitespace=False
15+
trim_whitespace=False,
16+
write_only=True
17+
)
18+
token = serializers.CharField(
19+
label=_("Token"),
20+
read_only=True
1321
)
1422

1523
def validate(self, attrs):

rest_framework/authtoken/views.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from rest_framework.compat import coreapi, coreschema
55
from rest_framework.response import Response
66
from rest_framework.schemas import ManualSchema
7+
from rest_framework.schemas import coreapi as coreapi_schema
78
from rest_framework.views import APIView
89

910

@@ -13,7 +14,8 @@ class ObtainAuthToken(APIView):
1314
parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,)
1415
renderer_classes = (renderers.JSONRenderer,)
1516
serializer_class = AuthTokenSerializer
16-
if coreapi is not None and coreschema is not None:
17+
18+
if coreapi_schema.is_enabled():
1719
schema = ManualSchema(
1820
fields=[
1921
coreapi.Field(
@@ -38,9 +40,19 @@ class ObtainAuthToken(APIView):
3840
encoding="application/json",
3941
)
4042

43+
def get_serializer_context(self):
44+
return {
45+
'request': self.request,
46+
'format': self.format_kwarg,
47+
'view': self
48+
}
49+
50+
def get_serializer(self, *args, **kwargs):
51+
kwargs['context'] = self.get_serializer_context()
52+
return self.serializer_class(*args, **kwargs)
53+
4154
def post(self, request, *args, **kwargs):
42-
serializer = self.serializer_class(data=request.data,
43-
context={'request': request})
55+
serializer = self.get_serializer(data=request.data)
4456
serializer.is_valid(raise_exception=True)
4557
user = serializer.validated_data['user']
4658
token, created = Token.objects.get_or_create(user=user)

tests/schemas/test_openapi.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from django.utils.translation import gettext_lazy as _
88

99
from rest_framework import filters, generics, pagination, routers, serializers
10+
from rest_framework.authtoken.views import obtain_auth_token
1011
from rest_framework.compat import uritemplate
1112
from rest_framework.parsers import JSONParser, MultiPartParser
1213
from rest_framework.renderers import JSONRenderer, OpenAPIRenderer
@@ -995,16 +996,45 @@ def test_serializer_model(self):
995996
patterns = [
996997
url(r'^example/?$', views.ExampleGenericAPIViewModel.as_view()),
997998
]
999+
9981000
generator = SchemaGenerator(patterns=patterns)
9991001

10001002
request = create_request('/')
10011003
schema = generator.get_schema(request=request)
10021004

10031005
print(schema)
1006+
10041007
assert 'components' in schema
10051008
assert 'schemas' in schema['components']
10061009
assert 'ExampleModel' in schema['components']['schemas']
10071010

1011+
def test_authtoken_serializer(self):
1012+
patterns = [
1013+
url(r'^api-token-auth/', obtain_auth_token)
1014+
]
1015+
generator = SchemaGenerator(patterns=patterns)
1016+
1017+
request = create_request('/')
1018+
schema = generator.get_schema(request=request)
1019+
1020+
print(schema)
1021+
1022+
route = schema['paths']['/api-token-auth/']['post']
1023+
body_schema = route['requestBody']['content']['application/json']['schema']
1024+
1025+
assert body_schema == {
1026+
'$ref': '#/components/schemas/AuthToken'
1027+
}
1028+
assert schema['components']['schemas']['AuthToken'] == {
1029+
'type': 'object',
1030+
'properties': {
1031+
'username': {'type': 'string', 'writeOnly': True},
1032+
'password': {'type': 'string', 'writeOnly': True},
1033+
'token': {'type': 'string', 'readOnly': True},
1034+
},
1035+
'required': ['username', 'password']
1036+
}
1037+
10081038
def test_component_name(self):
10091039
patterns = [
10101040
url(r'^example/?$', views.ExampleAutoSchemaComponentName.as_view()),

0 commit comments

Comments
 (0)