Search by name and surname

Advertisements

I have a search bar in template

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

In Model I have two seperate properties name and surname

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

In views.py I have logic like this

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

I want to filter with name surname or both of them

>Solution :

You use the bitwise or (|) operator to construct a logical or between two conditions, so:

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

or you can define the connector between the two conditions with:

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

You can also concatenate the two fields with Concat [Django-doc] and then filter with:

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))

But it is not a good idea to search with such queries: if one adds an extra space, or writes the names as surname followed by the name, this will not work.

If you want to do a full text search you need search technology. For example PostgreSQL’s full text engine and work with a SearchQuery [Django-doc] or a SearchQuery [Django-doc].

Another way to search is with search technology like Solr, ElasticSearch, etc. and then you can use django-haystack [readthedocs.io] to make calls to the search engine.

Leave a ReplyCancel reply