Skip to content
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

PrimaryKeyRelatedField with default=[] causes error #936

Closed
zx-zheng opened this issue Feb 16, 2023 · 2 comments
Closed

PrimaryKeyRelatedField with default=[] causes error #936

zx-zheng opened this issue Feb 16, 2023 · 2 comments
Labels
bug Something isn't working fix confirmation pending issue has been fixed and confirmation from issue reporter is pending

Comments

@zx-zheng
Copy link

Describe the bug
PrimaryKeyRelatedField with default=[] cause AttributeError: 'list' object has no attribute 'pk'.
I think it is common to use PrimaryKeyRelatedField with many=True and default=[]. But it looks default=[] causes errors.

To Reproduce

serializers.py

class UserSerializer(serializers.Serializer):
    groups = serializers.PrimaryKeyRelatedField(
        queryset=Group.objects.filter(), many=True, default=[]
    )

errors

Traceback (most recent call last):
  File "/Users/xxx/tmp/drf_quickstart/manage.py", line 22, in <module>
    main()
  File "/Users/xxx/tmp/drf_quickstart/manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/drf-quickstart-a3-4HLcc-py3.10/lib/python3.10/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
    utility.execute()
  File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/drf-quickstart-a3-4HLcc-py3.10/lib/python3.10/site-packages/django/core/management/__init__.py", line 440, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/drf-quickstart-a3-4HLcc-py3.10/lib/python3.10/site-packages/django/core/management/base.py", line 402, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/drf-quickstart-a3-4HLcc-py3.10/lib/python3.10/site-packages/django/core/management/base.py", line 448, in execute
    output = self.handle(*args, **options)
  File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/drf-quickstart-a3-4HLcc-py3.10/lib/python3.10/site-packages/drf_spectacular/management/commands/spectacular.py", line 72, in handle
    schema = generator.get_schema(request=None, public=True)
  File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/drf-quickstart-a3-4HLcc-py3.10/lib/python3.10/site-packages/drf_spectacular/generators.py", line 268, in get_schema
    paths=self.parse(request, public),
  File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/drf-quickstart-a3-4HLcc-py3.10/lib/python3.10/site-packages/drf_spectacular/generators.py", line 239, in parse
    operation = view.schema.get_operation(
  File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/drf-quickstart-a3-4HLcc-py3.10/lib/python3.10/site-packages/drf_spectacular/openapi.py", line 94, in get_operation
    operation['responses'] = self._get_response_bodies()
  File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/drf-quickstart-a3-4HLcc-py3.10/lib/python3.10/site-packages/drf_spectacular/openapi.py", line 1287, in _get_response_bodies
    return {'200': self._get_response_for_code(response_serializers, '200', direction=direction)}
  File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/drf-quickstart-a3-4HLcc-py3.10/lib/python3.10/site-packages/drf_spectacular/openapi.py", line 1343, in _get_response_for_code
    component = self.resolve_serializer(serializer, direction)
  File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/drf-quickstart-a3-4HLcc-py3.10/lib/python3.10/site-packages/drf_spectacular/openapi.py", line 1514, in resolve_serializer
    component.schema = self._map_serializer(serializer, direction, bypass_extensions)
  File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/drf-quickstart-a3-4HLcc-py3.10/lib/python3.10/site-packages/drf_spectacular/openapi.py", line 896, in _map_serializer
    schema = self._map_basic_serializer(serializer, direction)
  File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/drf-quickstart-a3-4HLcc-py3.10/lib/python3.10/site-packages/drf_spectacular/openapi.py", line 983, in _map_basic_serializer
    schema = self._map_serializer_field(field, direction)
  File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/drf-quickstart-a3-4HLcc-py3.10/lib/python3.10/site-packages/drf_spectacular/openapi.py", line 601, in _map_serializer_field
    meta = self._get_serializer_field_meta(field, direction)
  File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/drf-quickstart-a3-4HLcc-py3.10/lib/python3.10/site-packages/drf_spectacular/openapi.py", line 957, in _get_serializer_field_meta
    default = field.to_representation(field.default)
  File "/Users/xxx/Library/Caches/pypoetry/virtualenvs/drf-quickstart-a3-4HLcc-py3.10/lib/python3.10/site-packages/rest_framework/relations.py", line 273, in to_representation
    return value.pk
AttributeError: 'list' object has no attribute 'pk'

Expected behavior
No error.

@tfranzel tfranzel added the bug Something isn't working label Feb 16, 2023
tfranzel added a commit that referenced this issue Feb 16, 2023
this is not an complete fix but rather prevents an exception.
@tfranzel
Copy link
Owner

Yes this is a bug, we should never throw here. However, the actual mistake lies in DRF. They use the default value twice. This is what DRF creates:

# Your field
PrimaryKeyRelatedField(queryset=Group.objects.filter(), many=True, default=[])
# is translated by DRF to
ManyRelatedField(child_relation=PrimaryKeyRelatedField(default=[], queryset=Group.objects.filter()), default=[])

# this would be correct:
ManyRelatedField(child_relation=PrimaryKeyRelatedField(queryset=Group.objects.filter()), default=[])

So the outer default=[] is ok, but it makes no sense on the PrimaryKeyRelatedField, which is probably never used due to the wrapping field providing a default value. It is not trivial to account for this though.

I bugfixed the exception, but the schema is not perfect and I'm not particularly happy with it. You may want to fix it as described above.

@tfranzel tfranzel added the fix confirmation pending issue has been fixed and confirmation from issue reporter is pending label Feb 16, 2023
@zx-zheng
Copy link
Author

@tfranzel Thank you for your quick response! I confirmed the problem is solved.
I will also consider about fix the field as you described.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
bug Something isn't working fix confirmation pending issue has been fixed and confirmation from issue reporter is pending
Projects
None yet
Development

No branches or pull requests

2 participants