Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Allow users to overwrite
get_serializer_class
while using related urls #860New 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
Allow users to overwrite
get_serializer_class
while using related urls #860Changes from all commits
ff191c8
9f69484
a2b5704
5c4cb88
0366ceb
7e577d9
67d79ff
41785b8
e27b7a4
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removing this exposes the upstream DRF
get_serializer_class()
. It seems this needs to remain for compatibility. @sliverc Do you agree?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My whole point in making the change here is to do exactly this: expose the upstream method, so that it can be overwritten.
get_serializer_class()
is a public method on the base class. As such, it is part of DRF's public API - the DRF documentation explicitly mentions that the method can be overwritten. In my opinion, an extension library should preserve the upstream API.The current version of DJA does break the path to the upstream method. There might be cases where DJA users rely on this bug in some way. The change here would break their code. I'm just a first-time user of DJA without any idea about how it is being used in other projects, what the effects might be, and who might be affected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgive me for being dense but how is get_serializer_class() in DJA not able to be overridden by you? You've completely removed the function from DJA; not just added
get_related_serializer()
.This extension library routinely overrides the upstream DRF because it is extending it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do Full understand that you don't want to run the risk of breaking someone's application. And given that I am fairly new to DJA, I might not fully understand its inner workings, either.
I came across the issue the present PR is trying to solve, when I had to overwrite
get_serializer_class()
on a custom viewset, in exactly the same way I now added as part of theAuthorViewSet
in the test example. I investigated the issue and discovered that when processing a GET request for a related instance,RelatedMixin.get_related_instance()
directly accessed theself.serializer_class
field instead of getting the class via its accessor method. Consequently, the upstreamget_serializer_class()
would not be called, either, which would be my overwritten version. Hence my remark that DJA effectively preventsget_serializer_class()
to be overwritten on a custom viewset, which I consider to be a bug.My first attempt to fix the issue was to have
RelatedMixin.get_related_instance
call the upstream method instead of accessing the field directly. But this breaks things badly. During two exchanges with @sliverc (see the comments on the issue here) showed that the functionality ofRelatedMixin.get_serializer_class
is actually not about getting the serializer class, but getting the class of related serializers. I followed the hint of @sliverc to rename the method fromget_serializer_class()
toget_related_serializer_class()
, which better captures its functionality. This way,RelatedMixin.get_related_instance
can callget_serializer_class()
of the parent class (potentially overwritten), while all functionality that has to do with getting serializers for related views is now handled by aptly namedget_related_*
methods.To make this work, I need to do some other adjustments along the call chain. In particular,
retrieve_related()
, which is the entry point for a GET request on a related resource, now calls the renamedget_related_serializer_class()
. One more change, also pointed out by @sliverc, was inutils.get_resource_name()
: Here, I had to make the distinction if the serializer of the present viewset is needed, or if the serializer of a related viewset should be returned. The distinction between the two cases depends on therelated_field
kwarg, similar to the condition inget_serializer_class()
(notget_related_serializer_class()
.I hope this helps to provide some understanding of what I am trying to accomplish. I was very much focussed on the functionality of getting related resources; because of my limited understanding of DJA, I am not able to tell if other parts of its functionality are affected by the changes introduced in
RelatedMixin
. Here, I relied on the tests, which are all passing. If there is something else I can do to clear things up or to provide better explanation, please let me know. I am also available for a quick online call, if that can help to better assess the changes I introduced.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me try to shed some light on this...
RelatedMixin
mistakenly shadowedget_serializer_class
to get related serializer. Shadowing happened asRelatedMixin
only works when used with a DRF generic view which provides a get_serializer_class methodFor
RelatedMixin
to be able to get parent serializer it then simply usedself.serializer_class
which is not DRF conform. However this only happened when related urls have been configured as otherwise this if is always false and there is no difference to the method not being overwritten inRelatedMixin
.If someone overwrote
get_serializer_class
in its view without using related urls it would just work asRelatedMixin
did not do anything anyway in such a case then passing it on to super. If someone tried to overwriteget_serializer_class
with related urls this user would run into exactly the same problem as @uliSchuster has.Therefore I don't see that this change affects existing users.