Поиск по имени и фамилии

У меня есть строка поиска в шаблоне

<input type="text" name="search" placeholder="Search...">

В модели у меня есть два отдельных свойства имя и фамилия

class Person(models.Model):
    name = models.CharField(max_length=50)
    surname = models.CharField(max_length=50)

В файле views.py у меня есть такая логика

search = self.request.GET.get("search", None)
if search:
    Person.objects.filter(Q(name=search) | Q(surname=search))

Я хочу отфильтровать по имени фамилии или по обоим

Вы используете побитовый оператор or (|) для построения логического or между двумя условиями, так:

search = self.request.GET.get('search')
if search:
    Person.objects.filter(Q(name=search) | Q(surname=search))

или вы можете определить связь между двумя условиями с помощью:

if search:
    Person.objects.filter(Q(name=search, surname=search, _connector=Q.OR))

Вы также можете объединить два поля с помощью Concat [Django-doc] и затем отфильтровать с помощью:

from django.db.models import CharField, Value
from django.db.models.functions import Concat

if search:
    Person.objects.annotate(
        full_name=Concat('name', Value(' '), 'surname', output_field=CharField())
    ).filter(Q(name=search, surname=search, full_name=search, _connector=Q.OR))

Но поиск с помощью таких запросов - не самая лучшая идея: если добавить лишний пробел или написать имена как фамилию, за которой следует имя, это не сработает.

Если вы хотите выполнить полнотекстовый поиск, вам нужна поисковая технология. Например, PostgreSQL's full text engine и работа с SearchQuery [Django-doc] или SearchQuery [Django-doc].

Другой способ поиска - с помощью поисковых технологий, таких как Solr, ElasticSearch и т.д., а затем вы можете использовать django-haystack [readthedocs.io] для осуществления вызовов поисковой системы.

Вернуться на верх