Skip to content

SerializerMethodResourceRelatedField fails with queryset and many kwargs #779

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
glowka opened this issue Apr 11, 2020 · 2 comments · Fixed by #781
Closed

SerializerMethodResourceRelatedField fails with queryset and many kwargs #779

glowka opened this issue Apr 11, 2020 · 2 comments · Fixed by #781

Comments

@glowka
Copy link
Contributor

glowka commented Apr 11, 2020

Three cases below are OK, but the fourth one is surprisingly crashing

read_only is generally ok and non-read_only without many is also ok

SerializerMethodResourceRelatedField(
    model=Member, source='get_member', read_only=True
)

SerializerMethodResourceRelatedField(
    model=Member, source='get_members', read_only=True, many=True
)

SerializerMethodResourceRelatedField(
   queryset=Member.objects.all(), source='get_member'
)

But non-read_only with many crashes

relations.SerializerMethodResourceRelatedField(
    queryset=Member.objects.all(), source='get_members', many=True
)

Message:

tests/test_serializer_schema.py:388: in <module>
    source='get_members', many=True),
/site-packages/rest_framework_json_api/relations.py:361: in __new__
    return cls.many_init(*args, **kwargs)
/site-packages/rest_framework_json_api/relations.py:379: in many_init
    return cls(**list_kwargs)
/site-packages/rest_framework_json_api/relations.py:370: in __init__
    super(SerializerMethodResourceRelatedField, self).__init__(*args, **kwargs)
/site-packages/rest_framework_json_api/relations.py:192: in __init__
    super(ResourceRelatedField, self).__init__(**kwargs)
/site-packages/rest_framework_json_api/relations.py:76: in __init__
    super(HyperlinkedMixin, self).__init__(**kwargs)
/site-packages/rest_framework/relations.py:247: in __init__
    super().__init__(**kwargs)
/site-packages/rest_framework/relations.py:108: in __init__
    'Relational field must provide a `queryset` argument, '
E   AssertionError: Relational field must provide a `queryset` argument, 
override `get_queryset`, or set read_only=`True`

It looks like queryset is not passed correctly along the initialization.

My interpretation is that is probably due to a bit hacky implementation of SerializerMethodResourceRelatedField which tries to by SerializerMethodResourceRelatedField and ManySerializerMethodResourceRelatedField at the same time which looks to me prone to bugs like this.

So I would like to report this issue with SerializerMethodResourceRelatedField in the first place.

Additionally, if my perception of reasons of problems with SerializerMethodResourceRelatedField is more widely accepted I could refactor it and fix the bug at the same time.

@sliverc sliverc added the bug label Apr 11, 2020
@sliverc
Copy link
Member

sliverc commented Apr 11, 2020

The SerializerMethodResourceRelatedField follows the idea of the DRF SerializerMethodField so it should actually always be read only and applying a queryset doesn't really make sense therefore. This means to address this issue a read_only flag should be passed on to base class.

This field class does have other issues though like #639 so if you want to work on a PR which addresses these issues you are most welcome. Just keep in mind backwards compatibility respectively a deprecation path when refactoring.

@glowka
Copy link
Contributor Author

glowka commented Apr 13, 2020

Thanks for immediate response.

The SerializerMethodResourceRelatedField follows the idea of the DRF SerializerMethodField so it should actually always be read only and applying a queryset doesn't really make sense therefore. This means to address this issue a read_only flag should be passed on to base class.

OK, that makes sense now. Because of issues raised in #639 as well as no read_only enforcement (as in DRF SerializerMethodField ) I had not recognized it followed the same idea, actually when I realized the arguments (#639) worked in different manner I thought it might be implemented with a bit different approach. Hence the issue.

This field class does have other issues though like #639 so if you want to work on a PR which addresses these issues you are most welcome. Just keep in mind backwards compatibility respectively a deprecation path when refactoring.

I can't sign up for that now, but I feel the pain of #639, so in coming weeks I'll seriously consider doing that.

glowka added a commit to glowka/drf-yasg-json-api that referenced this issue Apr 13, 2020
Related to SerializerMethodResourceRelatedField and the issue
django-json-api/django-rest-framework-json-api#779
glowka added a commit to glowka/django-rest-framework-json-api that referenced this issue Apr 15, 2020
glowka added a commit to glowka/django-rest-framework-json-api that referenced this issue Apr 15, 2020
glowka added a commit to glowka/django-rest-framework-json-api that referenced this issue Apr 22, 2020
sliverc pushed a commit that referenced this issue May 3, 2020
Fixes #639 - interface not consistent with `SerializerMethodField`
Fixes #779 - no enforcement of `read_only`
Fixes #780 - broken `parent` chain
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants