mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-16 19:41:06 +03:00
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.
This commit is contained in:
parent
fd32dd7ca4
commit
86c72bb226
|
@ -51,8 +51,10 @@ def field_to_schema(field):
|
|||
description=description
|
||||
)
|
||||
elif isinstance(field, serializers.ManyRelatedField):
|
||||
related_field_schema = field_to_schema(field.child_relation)
|
||||
|
||||
return coreschema.Array(
|
||||
items=coreschema.String(),
|
||||
items=related_field_schema,
|
||||
title=title,
|
||||
description=description
|
||||
)
|
||||
|
|
|
@ -24,7 +24,7 @@ from rest_framework.utils import formatting
|
|||
from rest_framework.views import APIView
|
||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||
|
||||
from .models import BasicModel, ForeignKeySource
|
||||
from .models import BasicModel, ForeignKeySource, ManyToManySource
|
||||
|
||||
factory = APIRequestFactory()
|
||||
|
||||
|
@ -701,6 +701,51 @@ class TestSchemaGeneratorWithForeignKey(TestCase):
|
|||
assert schema == expected
|
||||
|
||||
|
||||
class ManyToManySourceSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = ManyToManySource
|
||||
fields = ('id', 'name', 'targets')
|
||||
|
||||
|
||||
class ManyToManySourceView(generics.CreateAPIView):
|
||||
queryset = ManyToManySource.objects.all()
|
||||
serializer_class = ManyToManySourceSerializer
|
||||
|
||||
|
||||
@unittest.skipUnless(coreapi, 'coreapi is not installed')
|
||||
class TestSchemaGeneratorWithManyToMany(TestCase):
|
||||
def setUp(self):
|
||||
self.patterns = [
|
||||
url(r'^example/?$', ManyToManySourceView.as_view()),
|
||||
]
|
||||
|
||||
def test_schema_for_regular_views(self):
|
||||
"""
|
||||
Ensure that AutoField many to many fields 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('targets', required=True, location='form', schema=coreschema.Array(title='Targets', items=coreschema.Integer())),
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
assert schema == expected
|
||||
|
||||
|
||||
@unittest.skipUnless(coreapi, 'coreapi is not installed')
|
||||
class Test4605Regression(TestCase):
|
||||
def test_4605_regression(self):
|
||||
|
|
Loading…
Reference in New Issue
Block a user