Search code examples
djangodjango-queryset

Django Q object AND operation not working


I have a listview of people with a filter. The filter has the following code:

    if textquery:
        qs = qs.filter()

        qs = qs.filter(Q(name__icontains=textquery) |
                       Q(surname__icontains=textquery) |
                       Q(surname__icontains=textquery) & Q(name__icontains=textquery)
                       )


    return qs

People can have both a first and a last name, and searching for those works as expected. However, when I input both the first AND the lastname, the program does not return any results (even though I thought that the '&' operation in the end should include both variables).

In summary: this is currently the result of my queries:

Person: 'John Doe' 
Query:  'John' 
Result: 'John Doe' 

Person: 'John Doe' 
Query: 'Doe'
Result: 'John Doe'

Person 'John Doe'
Query: 'Johh Doe'
Result: ''

Does anyone know what I am doing wrong, and why matches for both the NAME and SURNAME do not return any results?


Solution

  • @neverwalkaloner has it right. You can use their solution or try this one below, it combines the name and surname together and make the solution more flexible. So now if even the textquery is "n D" it still matches.

    from django.db.models.functions import Concat
    from django.db.models import F, Value
    
    qs = qs.annotate(fullname=Concat(F('name'), Value(' '), F('surname')))\
                .filter(fullname__icontains=textquery)