-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
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
fix DISTINCT for Oracle databases #2935
Changes from 5 commits
7813d2f
c47ec60
de95598
0906bf2
745d8d0
e8b23c4
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 |
---|---|---|
|
@@ -7,6 +7,7 @@ | |
from django.core.exceptions import ImproperlyConfigured | ||
from django.db import models | ||
from django.utils import six | ||
from django.conf import settings | ||
from rest_framework.compat import django_filters, guardian, get_model_name | ||
from rest_framework.settings import api_settings | ||
from functools import reduce | ||
|
@@ -100,12 +101,19 @@ def filter_queryset(self, request, queryset, view): | |
|
||
orm_lookups = [self.construct_search(six.text_type(search_field)) | ||
for search_field in search_fields] | ||
|
||
and_queries = [] | ||
for search_term in self.get_search_terms(request): | ||
or_queries = [models.Q(**{orm_lookup: search_term}) | ||
for orm_lookup in orm_lookups] | ||
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'd prefer it if we didn't introduce the |
||
queryset = queryset.filter(reduce(operator.or_, or_queries)).distinct() | ||
|
||
and_queries.append(reduce(operator.or_, or_queries)) | ||
|
||
if and_queries: | ||
# According to Oracle DB limits there is no capability to make a DISTINT on *LOB | ||
if settings.DATABASES[queryset.db]["ENGINE"] == "django.db.backends.oracle": | ||
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. We'll want a brief comment here regarding needing this behavior for oracle and distinct. 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. @tomchristie According to Oracle DB limits there is no capability to make a DISTINT on *LOB. There is a need to use 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. Clarification: I was meaning that we should have a code comment for this. |
||
pk_list = queryset.filter(reduce(operator.and_, and_queries)).values_list('pk', flat=True) | ||
return queryset.filter(pk__in=frozenset(pk_list)) | ||
else: | ||
return queryset.filter(reduce(operator.and_, and_queries)).distinct() | ||
return queryset | ||
|
||
|
||
|
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.
Not sure I understand the motivation here - feels more obscure after this change rather than more clear.
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 sure, if calling
queryset.filter(pk_in=set(pk_list))
will make duplications go away, as theypk
still will be inpk_list
. I want to filter originalqueryset
bypk_list
.When we call
filter
with multiple kwargs or several times on one queryset it is equal to logicaland
.