Search by name and surname

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.