Query identity operation

68 views
Skip to first unread message

Leon Albrecht

unread,
Dec 20, 2020, 12:19:03 PM12/20/20
to Django developers (Contributions to Django itself)
Hey everyone,

I'm running a website, that uses a search bar, and to parse said search bar, I "and" together multiple queries in a loop,
but to start of I need a Identity-Query, that does nothing and return everything.
There are solutions to create one, but they aren't free and do not look good or intuitive.

So I suggest adding a Identity-Query object, which gets discarded by the optimizer during the SQL generation stage.

Leon

PS:
Just using multiple filters wont work, because they always use the original data set and unify all results at the end.

PPS:
An issue that occurred me is that "and"-ing together queries may cause the results to be duplicate.

Adam Johnson

unread,
Dec 20, 2020, 12:33:07 PM12/20/20
to django-d...@googlegroups.com
How is this different from QuerySet.all() ? Can you give a code example of what you'd imagine this API doing?

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/65ce7659-9101-4d60-89be-28b076f97f13n%40googlegroups.com.


--
Adam

Leon Albrecht

unread,
Dec 20, 2020, 2:03:58 PM12/20/20
to Django developers (Contributions to Django itself)
OK no clue, why it didn't send my answer from 15min ago but,
I will give an example similar to my exact use case:

...
search_query = request.GET.get("q""").lower() # string of features the user searches for separated by whitespaces
complete_query = ~Q(pk__in=[]) # this should be something like Q.ident()

for query in search_query.split():
  complete_query &= (
    Q(author__first_name__icontains = query) |
    Q(author__last_name__icontains = query) |
    Q(year = query if query.isdigit() else  -1) |
    Q(title__icontains = query)
    )

books= Book.objects.filter(complete_query).distinct() # distinct() is fo rthe issue described in the PPS

... # render page with relevant books


----
Leon

PS:
Does this service allow inline html, could have been the reason why it wasn't send or it just takes a while and I'm to imaptient

Leon Albrecht

unread,
Dec 20, 2020, 2:03:58 PM12/20/20
to Django developers (Contributions to Django itself)
Ok, I will follow with exemplary code similar to the one i use:
<code>
...
searchquery = request.GET["q"]
complete_query = ~Q(pk__in=[])  # this should be something like Q.ident()
            for query in search_query.split():
                complete_query &= (
                    Q(autor__first_name__icontains=query) |
                    Q(author__last_name__icontains=query) |
                    Q(title__icontains=query) |
                    Q(year=int(query) if query.isdigit() else -1)
                )
            books = Book.obejects.filter(complete_query).distinct() # the distinct is for the issue described in the PPS

... # render page with the filtered books
</code>

in the Example the searchquery is a string of features seperated by whitespaces the user wants to search for and the Book model is similar to the one described in the django tutorials, if I remember them right.

Mariusz Felisiak

unread,
Dec 21, 2020, 12:21:40 AM12/21/20
to Django developers (Contributions to Django itself)
complete_query = ~Q(pk__in=[])  # this should be something like Q.ident()

You can use `complete_query = Q()`. Also, this mailing list is for discussing the development of Django itself, not for support using Django.
 
Best,
Mariusz

Adam Johnson

unread,
Dec 21, 2020, 9:45:53 AM12/21/20
to django-d...@googlegroups.com
I saw that Q() with no arguments is not documented, so I've made a PR to add a sentence covering it: https://github.com/django/django/pull/13798 .

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.


--
Adam

Ken Whitesell

unread,
Dec 21, 2020, 10:30:34 AM12/21/20
to django-d...@googlegroups.com
A couple questions came to mind if we're going to document this as "official behavior":

1. This also appears to be true for filter. Would the same clarification be appropriate there?

2. I don't see any tests validating the behavior for either Q or filter, should there be?

Ken

Adam Johnson

unread,
Dec 21, 2020, 11:09:56 AM12/21/20
to django-d...@googlegroups.com
1. Sure, pushed a commit

Please leave PR-specific feedback on GitHub in future :)



--
Adam
Reply all
Reply to author
Forward
0 new messages