Skip to content

Commit 27f32fa

Browse files
jlainecarltongibson
authored andcommitted
Fix schema generation for PrimaryKeyRelatedField (#5764)
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.
1 parent 3c7b3ac commit 27f32fa

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

rest_framework/schemas/inspectors.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ def field_to_schema(field):
5050
title=title,
5151
description=description
5252
)
53+
elif isinstance(field, serializers.PrimaryKeyRelatedField):
54+
schema_cls = coreschema.String
55+
model = getattr(field.queryset, 'model', None)
56+
if model is not None:
57+
model_field = model._meta.pk
58+
if isinstance(model_field, models.AutoField):
59+
schema_cls = coreschema.Integer
60+
return schema_cls(title=title, description=description)
5361
elif isinstance(field, serializers.RelatedField):
5462
return coreschema.String(title=title, description=description)
5563
elif isinstance(field, serializers.MultipleChoiceField):

tests/test_schemas.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from rest_framework.views import APIView
2424
from rest_framework.viewsets import GenericViewSet, ModelViewSet
2525

26-
from .models import BasicModel
26+
from .models import BasicModel, ForeignKeySource
2727

2828
factory = APIRequestFactory()
2929

@@ -556,6 +556,51 @@ def test_schema_for_regular_views(self):
556556
assert schema == expected
557557

558558

559+
class ForeignKeySourceSerializer(serializers.ModelSerializer):
560+
class Meta:
561+
model = ForeignKeySource
562+
fields = ('id', 'name', 'target')
563+
564+
565+
class ForeignKeySourceView(generics.CreateAPIView):
566+
queryset = ForeignKeySource.objects.all()
567+
serializer_class = ForeignKeySourceSerializer
568+
569+
570+
@unittest.skipUnless(coreapi, 'coreapi is not installed')
571+
class TestSchemaGeneratorWithForeignKey(TestCase):
572+
def setUp(self):
573+
self.patterns = [
574+
url(r'^example/?$', ForeignKeySourceView.as_view()),
575+
]
576+
577+
def test_schema_for_regular_views(self):
578+
"""
579+
Ensure that AutoField foreign keys are output as Integer.
580+
"""
581+
generator = SchemaGenerator(title='Example API', patterns=self.patterns)
582+
schema = generator.get_schema()
583+
584+
expected = coreapi.Document(
585+
url='',
586+
title='Example API',
587+
content={
588+
'example': {
589+
'create': coreapi.Link(
590+
url='/example/',
591+
action='post',
592+
encoding='application/json',
593+
fields=[
594+
coreapi.Field('name', required=True, location='form', schema=coreschema.String(title='Name')),
595+
coreapi.Field('target', required=True, location='form', schema=coreschema.Integer(description='Target', title='Target')),
596+
]
597+
)
598+
}
599+
}
600+
)
601+
assert schema == expected
602+
603+
559604
@unittest.skipUnless(coreapi, 'coreapi is not installed')
560605
class Test4605Regression(TestCase):
561606
def test_4605_regression(self):

0 commit comments

Comments
 (0)