8000 Fix schema generation of `ManyRelatedField` to detect the child type … · encode/django-rest-framework@86c72bb · GitHub
[go: up one dir, main page]

Skip to content

Commit 86c72bb

Browse files
kevin-browncarltongibson
authored andcommitted
Fix schema generation of ManyRelatedField to detect the child type (#6489)
* Introspect ManyRelatedField data type recursively For all `ManyRelatedField` objects, we were assuming that the inner type was always a `String`. While this may be true for the default output, a `ManyRelatedField` is a wrapper for a lot of other classes which includes more than just strings. This should allow us to document lists of things other than strings. * Added test for schemas for many-to-many fields This adds a test that makes sure we generate the schema for a many-to-many field such that it actually has the right type. For some reason we did not previously have any tests for schema generation that included them, so hopefully this will prevent any future issues from popping up. This should serve as a regression test for the `items` field on to-many relationships, which was previously forced to a `String` even though in most cases it is a different inner type within the array.
1 parent fd32dd7 commit 86c72bb

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

rest_framework/schemas/inspectors.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ def field_to_schema(field):
5151
description=description
5252
)
5353
elif isinstance(field, serializers.ManyRelatedField):
54+
related_field_schema = field_to_schema(field.child_relation)
55+
5456
return coreschema.Array(
55-
items=coreschema.String(),
57+
items=related_field_schema,
5658
title=title,
5759
description=description
5860
)

tests/test_schemas.py

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

27-
from .models import BasicModel, ForeignKeySource
27+
from .models import BasicModel, ForeignKeySource, ManyToManySource
2828

2929
factory = APIRequestFactory()
3030

@@ -701,6 +701,51 @@ def test_schema_for_regular_views(self):
701701
assert schema == expected
702702

703703

704+
class ManyToManySourceSerializer(serializers.ModelSerializer):
705+
class Meta:
706+
model = ManyToManySource
707+
fields = ('id', 'name', 'targets')
708+
709+
710+
class ManyToManySourceView(generics.CreateAPIView):
711+
queryset = ManyToManySource.objects.all()
712+
serializer_class = ManyToManySourceSerializer
713+
714+
715+
@unittest.skipUnless(coreapi, 'coreapi is not installed')
716+
class TestSchemaGeneratorWithManyToMany(TestCase):
717+
def setUp(self):
718+
self.patterns = [
719+
url(r'^example/?$', ManyToManySourceView.as_view()),
720+
]
721+
722+
def test_schema_for_regular_views(self):
723+
"""
724+
Ensure that AutoField many to many fields are output as Integer.
725+
"""
726+
generator = SchemaGenerator(title='Example API', patterns=self.patterns)
727+
schema = generator.get_schema()
728+
729+
expected = coreapi.Document(
730+
url='',
731+
title='Example API',
732+
content={
733+
'example': {
734+
'create': coreapi.Link(
735+
url='/example/',
736+
action='post',
737+
encoding='application/json',
738+
fields=[
739+
coreapi.Field('name', required=True, location='form', schema=coreschema.String(title='Name')),
740+
coreapi.Field('targets', required=True, location='form', schema=coreschema.Array(title='Targets', items=coreschema.Integer())),
741+
]
742+
)
743+
}
744+
}
745+
)
746+
assert schema == expected
747+
748+
704749
@unittest.skipUnless(coreapi, 'coreapi is not installed')
705750
class Test4605Regression(TestCase):
706751
def test_4605_regression(self):

0 commit comments

Comments
 (0)
0