В данный момент ваш синтаксический анализ вообще не разбивает запрос, вы можете сделать это, просмотреть результаты и создать себе объект Q для размещения в запросе.
import operator
queries = request.GET.get('q').split()
qset1 = reduce(operator.__or__, [Q(first_name__icontains=query) | Q(last_name__icontains=query) for query in queries])
results = UserProfile.objects.filter(qset1).distinct()
То, что это в основном будет делать, это разбивать запрос на части и циклически проходить каждое слово, выполняя в точности то, что вы уже делаете. Поэтому, если они ищут «Фрэнк Подольски», он проверит, что «Фрэнк» находится в имени, фамилии, а затем, если «Подольский» также в имени, фамилии, а не в запросе в целом.
Конечно, вы можете сделать гораздо больше, чтобы улучшить поиск, например, определение слов, удаление стоп-слов и т. Д., Но это выходит за рамки этого вопроса.