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.