Fix schema generation for PrimaryKeyRelatedField

By default all subclasses of RelatedField are output as string fields in
the schema, which works well for StringRelatedField, SlugRelatedField or
HyperlinkedRelatedField.

Handle the common case of a PrimaryKeyRelatedField pointing to an
AutoField.
This commit is contained in:
Jeremy Lainé 2018-01-23 15:46:40 +01:00
parent 78367ba102
commit 6e4ad2565c
2 changed files with 54 additions and 1 deletions

View File

@ -50,6 +50,14 @@ def field_to_schema(field):
title=title,
description=description
)
elif isinstance(field, serializers.PrimaryKeyRelatedField):
schema_cls = coreschema.String
model = getattr(field.queryset, 'model', None)
if model is not None:
model_field = model._meta.pk
if isinstance(model_field, models.AutoField):
schema_cls = coreschema.Integer
return schema_cls(title=title, description=description)
elif isinstance(field, serializers.RelatedField):
return coreschema.String(title=title, description=description)
elif isinstance(field, serializers.MultipleChoiceField):

View File

@ -25,7 +25,7 @@ from rest_framework.utils import formatting
from rest_framework.views import APIView
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from .models import BasicModel
from .models import BasicModel, ForeignKeySource
factory = APIRequestFactory()
@ -558,6 +558,51 @@ class TestSchemaGeneratorWithRestrictedViewSets(TestCase):
assert schema == expected
class ForeignKeySourceSerializer(serializers.ModelSerializer):
class Meta:
model = ForeignKeySource
fields = ('id', 'name', 'target')
class ForeignKeySourceView(generics.CreateAPIView):
queryset = ForeignKeySource.objects.all()
serializer_class = ForeignKeySourceSerializer
@unittest.skipUnless(coreapi, 'coreapi is not installed')
class TestSchemaGeneratorWithForeignKey(TestCase):
def setUp(self):
self.patterns = [
url(r'^example/?$', ForeignKeySourceView.as_view()),
]
def test_schema_for_regular_views(self):
"""
Ensure that AutoField foreign keys are output as Integer.
"""
generator = SchemaGenerator(title='Example API', patterns=self.patterns)
schema = generator.get_schema()
expected = coreapi.Document(
url='',
title='Example API',
content={
'example': {
'create': coreapi.Link(
url='/example/',
action='post',
encoding='application/json',
fields=[
coreapi.Field('name', required=True, location='form', schema=coreschema.String(title='Name')),
coreapi.Field('target', required=True, location='form', schema=coreschema.Integer(description='Target', title='Target')),
]
)
}
}
)
assert schema == expected
@unittest.skipUnless(coreapi, 'coreapi is not installed')
class Test4605Regression(TestCase):
def test_4605_regression(self):