-
Notifications
You must be signed in to change notification settings - Fork 301
Allow overwriting of get_queryset() of related field #415
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -150,7 +150,7 @@ def to_internal_value(self, data): | |
if not isinstance(data, dict): | ||
self.fail('incorrect_type', data_type=type(data).__name__) | ||
|
||
expected_relation_type = get_resource_type_from_queryset(self.queryset) | ||
expected_relation_type = get_resource_type_from_queryset(self.get_queryset()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like this use of get_queryset() instead of queryset as some of the mixins I've proposed in #416 take advantage of queryset stacking with, for example, Are there other places in the code where There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have searched through the code and found one more in the documentation and the It is adjusted now. |
||
serializer_resource_type = self.get_resource_type_from_included_serializer() | ||
|
||
if serializer_resource_type is not None: | ||
|
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.
Any reason not to just use
self.queryset = ...
rather than creating a new localqueryset
variable? That would lead to a more consistent code style (see #416).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.
If I used
self.queryset
the output ofget_queryset
might be different when callingget_queryset
several times and we certainly want to avoid this.Hope this makes it clear otherwise let me know.
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 don't think so:
self.queryset
as an lvalue is updated as the return value ofself.get_queryset()
. Worst case, it gets the exact same value thatget_queryset()
sets it to. You always want the result of the lastget_queryset
to be inself.queryset
.Am I misunderstanding something here? My tests with the new Mixins bear this out. Stacking several Mixins does the "right" thing, building up a list of object manager calls to further narrow the query set.
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 outline what happens when we overwrite
self.queryset
andget_queryset
gets called multiple times.This is just a simplified pseudo version of what actually happens in DRF:
When
self.queryset
is not overwritten the result of the 2nd call is the same as the first call. In my above example the query is not the same but the result will still be the same. However there might be even example where results might be different when traversing throughManyToMany
relations and several joins happens.Hope this explains.
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.
@sliverc Sorry, I still don't see how setting
self.queryset
is incorrect. Following is a log where I've added prints to the mixins on entry and exit and the expected behavior is happening for this request:At class definition:
and then execution of the above GET:
The lines with
(0.000)
are the SQL fromdjango.db.backends
logging.Here's the code that includes the prints:
Since all the super methods do the same thing: setting
self.queryset
and then returning it, it doesn't seem to matter if I use a local variable instead ofself.queryset
, except if there's some other code elsewhere in DJA or DRF that just referencesself.queryset
instead of callingget_queryset
, which is entirely possible. So it's a belt-and-suspenders, but not broken.If
get_queryset()
were instead an@property queryset()
getter forself.queryset
, then referencingself.queryset
would be guaranteed to call the getter, but it is not, so not only does it not hurt to setself.queryset
inget_queryset()
but it guarantees that it's got the latest value in case it's used directly.I hope this makes sense.
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.
@sliverc OK, so after writing all the above I've taken a look at DRF's use of queryset and now I think I understand it a little better.
Never mind! I'll dismiss my suggestion and merge.