Аннотируйте полное имя через Concat и Coalesce, уберите крайние пробелы через Trim, затем фильтруйте по нормализованной строке.
Поиск пользователя по составному ФИО
Аннотируйте полное имя через Concat и Coalesce, уберите крайние пробелы через Trim, затем фильтруйте по нормализованной строке.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Сформировать запрос в Django ORM, который осуществит поиск записи пользователя, используя полное ФИО, сформированное из полей last_name, first_name и middle_name.
class User(models.Model):
last_name = models.CharField('Фамилия', max_length=128)
first_name = models.CharField('Имя', max_length=128)
middle_name = models.CharField('Отчество', max_length=128, blank=True, null=True)
class Employee(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
Ответ
Аннотируйте полное имя через Concat и Coalesce, уберите крайние пробелы через Trim, затем фильтруйте по нормализованной строке.
from django.db.models import Value, CharField
from django.db.models.functions import Concat, Coalesce, Trim
full_name = ' '.join(input_name.split())
users = User.objects.annotate(
full_name=Trim(Concat(
'last_name', Value(' '), 'first_name', Value(' '),
Coalesce('middle_name', Value('')),
output_field=CharField(),
))
).filter(full_name=full_name)
Coalesce обрабатывает отсутствующее отчество, а Trim убирает последний пробел. Предполагается, что отдельные поля при записи уже очищены от лишних пробелов. ФИО не гарантирует уникальность, поэтому filter безопаснее безусловного get. Для поиска по Employee используйте пути user__last_name и аналогичные. На больших таблицах вычисляемая конкатенация может потребовать отдельного поискового индекса.