-
Notifications
You must be signed in to change notification settings - Fork 273
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
is_patched_serializer
fails with DictField
#413
Comments
hi. i cannot reproduce this issue. also this does not look like the newest version. the following example has worked for me. def test_list_dict_field(no_warnings):
class XAPIView(APIView):
@extend_schema(responses=serializers.ListSerializer(child=serializers.DictField()))
def get(self, request):
pass # pragma: no cover
schema = generate_schema('x', view=XAPIView) |
Thanks for the example. That helped me write the reproduction test. The problem manifests itself for a def test_list_dict_field(no_warnings):
from django.urls import path
from drf_spectacular.generators import SchemaGenerator
from drf_spectacular.utils import extend_schema
from drf_spectacular.validation import validate_schema
from rest_framework.generics import ListAPIView
from rest_framework.serializers import DictField, ListSerializer
class XAPIView(ListAPIView):
@extend_schema(responses=ListSerializer(child=DictField()))
def get(self, request):
pass # pragma: no cover
generator = SchemaGenerator(patterns=[path('v1/x', XAPIView.as_view())])
schema = generator.get_schema(request=None, public=True)
validate_schema(schema) |
hey @mblayman, i still cannot reproduce the issue. at least on the current are you using the most recent version there? although i cannot remember any fixes there in the past couple of releases. |
We weren't when I reported this. I can try again on 0.17.0 (hopefully later today) and report if I can replicate the issue still. |
I ran this same test that I have above with 0.17.0 and it still fails for me. Is there anything else I could provide to help replicate this? def test_list_dict_field(no_warnings):
from django.urls import path
from drf_spectacular.generators import SchemaGenerator
from drf_spectacular.utils import extend_schema
from drf_spectacular.validation import validate_schema
from rest_framework.generics import ListAPIView
from rest_framework.serializers import DictField, ListSerializer
class XAPIView(ListAPIView):
@extend_schema(responses=ListSerializer(child=DictField()))
def get(self, request):
pass # pragma: no cover
generator = SchemaGenerator(patterns=[path('v1/x', XAPIView.as_view())])
> schema = generator.get_schema(request=None, public=True)
bhps/tests/test_views.py:1952:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/local/lib/python3.7/site-packages/drf_spectacular/generators.py:257: in get_schema
paths=self.parse(request, public),
/usr/local/lib/python3.7/site-packages/drf_spectacular/generators.py:232: in parse
path, path_regex, path_prefix, method, self.registry
/usr/local/lib/python3.7/site-packages/drf_spectacular/utils.py:274: in get_operation
return super().get_operation(path, path_regex, path_prefix, method, registry)
/usr/local/lib/python3.7/site-packages/drf_spectacular/openapi.py:84: in get_operation
operation['responses'] = self._get_response_bodies()
/usr/local/lib/python3.7/site-packages/drf_spectacular/openapi.py:1001: in _get_response_bodies
return {'200': self._get_response_for_code(response_serializers, '200')}
/usr/local/lib/python3.7/site-packages/drf_spectacular/openapi.py:1075: in _get_response_for_code
paginated_name = f'Paginated{self._get_serializer_name(serializer, "response")}List'
/usr/local/lib/python3.7/site-packages/drf_spectacular/openapi.py:1155: in _get_serializer_name
return self._get_serializer_name(serializer.child, direction)
/usr/local/lib/python3.7/site-packages/drf_spectacular/openapi.py:1162: in _get_serializer_name
if is_patched_serializer(serializer, direction):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
serializer = DictField(), direction = 'response'
def is_patched_serializer(serializer, direction):
return bool(
spectacular_settings.COMPONENT_SPLIT_PATCH
> and serializer.partial
and not serializer.read_only
and not (spectacular_settings.COMPONENT_SPLIT_REQUEST and direction == 'response')
)
E AttributeError: 'DictField' object has no attribute 'partial'
/usr/local/lib/python3.7/site-packages/drf_spectacular/plumbing.py:97: AttributeError |
the stacktrace contains a line that is only reached by using pagination. Since you have no pagination class in your example, i have to assume that you have a global default setting. with a added pagination class i can reproduce the error. |
That's right. We're using the REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
...
} |
that was a small but important detail |
so i analyzed this issue. it's definitely an edge case. in theory this is not supported. theoretically the more correct version would have been on the other hand i can see the need for this. since there is no other way expressing what you need and its a very reasonable ask, i think it's acceptable to be lenient here and "do the right thing" even though it would be technically incorrect. |
strictly speaking this is not correct but it's the only way to specify a unnamed list with extend_schema. also the unpaginated version we do already support.
this should fix it. i also noticed that we support this for unpaginated endpoints. so having parity again is another benefit. |
Thank you for digging into this and fixing it up. I appreciate your attention to detail. |
closing this issue for now. feel free to comment if anything is missing or not working and we will follow-up. |
Describe the bug
My team has a list endpoint that returns a dictionary values that are generated by methods that aren't serializers. We'd like to document at least that this endpoint returns a list of objects. I tried adding the following
extend_schema
:drf-spectacular raised the following exception:
Expected behavior
Since this should be a valid serializer (test proving that is below), I'd expect the
is_patched_serializer
to handle aDictField
.The text was updated successfully, but these errors were encountered: