drf-yasg
drf-yasg copied to clipboard
Exception when using SlugRelatedField(many=True, default=list)
When using the following serializer:
class ObjectSerializer(serializers.ModelSerializer):
m2m_field = serializers.SlugRelatedField(
queryset=Field.objects.all(), many=True, slug_field='code',
source='m2m', write_only=True, default=list
)
When the schema generator is run, I get the following exception:
'default' on schema for SlugRelatedField(default=<class 'list'>, queryset=<QuerySet [<Field: Field object (1)>]>, slug_field='code', source='m2m', write_only=True) will not be set because to_representation raised an exception
Traceback (most recent call last):
File "venv/lib/python3.7/site-packages/drf_yasg/utils.py", line 484, in get_field_default
default = field_value_to_representation(field, default)
File "venv/lib/python3.7/site-packages/drf_yasg/utils.py", line 451, in field_value_to_representation
value = field.to_representation(value)
File "venv/lib/python3.7/site-packages/rest_framework/relations.py", line 460, in to_representation
return getattr(obj, self.slug_field)
AttributeError: 'list' object has no attribute 'code'
I can prevent the exception if I use ManyRelatedField
directly, but the documentation says not to use it.
I get the same issue in a normal Serializer, it attempts to find the serializer fields in the empty list since it's the default value
class ChildSerializer(serializers.Serializer):
something = serializers.CharField()
class ParentSerializer(serializers.Serializer):
value = ChildSerializer(many=True, default=[])
returns:
Traceback (most recent call last):
File ".../venv/lib/python3.6/site-packages/drf_yasg/utils.py", line 497, in get_field_default
default = field_value_to_representation(field, default)
File ".../venv/lib/python3.6/site-packages/drf_yasg/utils.py", line 461, in field_value_to_representation
value = field.to_representation(value)
File ".../venv/lib/python3.6/site-packages/rest_framework/serializers.py", line 502, in to_representation
attribute = field.get_attribute(instance)
File ".../venv/lib/python3.6/site-packages/rest_framework/fields.py", line 490, in get_attribute
raise type(exc)(msg)
AttributeError: Got AttributeError when attempting to get a value for field `something` on serializer `ChildSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `list` instance.
Original exception text was: 'list' object has no attribute 'something'.
I guess many=True with default=list should be taken into account in utils:get_field_default() maybe something like the following?
in https://github.com/axnsan12/drf-yasg/blob/1.20.0/src/drf_yasg/utils.py#L495
...
many = getattr(field, 'many', False)
if default is not serializers.empty and default is not None and not (many is True and default in [list, []]):
try:
default = field_value_to_representation(field, default)
...
I'm not aware of the effects this might have so it's just an initial idea :)