Поиск имени и фамилии в Джанго - PullRequest
2 голосов
/ 28 марта 2019

У меня есть эта модель на Django:

class Profile(models.Model):
  name = models.CharField(max_length=50, blank = False)
  surname = models.CharField(max_length=100, blank = False)
  ...

Например, у меня есть 2 профиля в базе данных:

  • Джон Доу
  • Джон Смит

Я хочу выполнить поиск формы, который выполняет поиск по атрибутам имени и фамилии.

Я попытался:

Q(name__icontains=text) | Q(surname__icontains=text)

Но это не работает,например, если я ищу «Джон Доу», он возвращает их обоих.

Редактировать : В основном я хочу что-то вроде «объединения» атрибутов имени и фамилии для поиска, поэтому, когдаЯ ищу "Джон", он показывает мне "Джон Доу" и "Джон Смит", а когда я ищу "Джон Доу", он показывает мне только профиль "Джон Доу". ​​

Ответы [ 2 ]

2 голосов
/ 28 марта 2019

Попробуйте,

from django.db.models import Value as V
from django.db.models.functions import Concat

text = "John Doe"
Profile.objects.annotate(full_name=Concat('name', V(' '), 'surname')).filter(full_name__icontains=text)

Ссылка

  1. Concat Функция DB
  2. Фильтр набора запросов Django после объединения двух столбцов

Вывод оболочки Django

In [14]: from django.db.models import Value as V                                                                                                                                                                   

In [15]: from django.db.models.functions import Concat                                                                                                                                                             

In [16]: text = "John Doe"                                                                                                                                                                                         

In [17]: Profile.objects.annotate(full_name=Concat('name', V(' '), 'surname')).filter(full_name__icontains=text)                                                                                                   
Out[17]: <QuerySet [<Profile: John Doe>]>

In [18]: text = "john"                                                                                                                                                                                             

In [19]: Profile.objects.annotate(full_name=Concat('name', V(' '), 'surname')).filter(full_name__icontains=text)                                                                                                   
Out[19]: <QuerySet [<Profile: John Doe>, <Profile: John Smith>]>

In [20]: text="smith"                                                                                                                                                                                              

In [21]: Profile.objects.annotate(full_name=Concat('name', V(' '), 'surname')).filter(full_name__icontains=text)                                                                                                   
Out[21]: <QuerySet [<Profile: John Smith>]>
1 голос
/ 28 марта 2019

Это измененная копия / вставка из этого ответа .

Я пытался придумать разные способы, но все они требовали подсчета строк после каждого запроса, что потребовало бы действительно много времени. Вместо этого лучше всего разделить текст на пробелы и применить к нему фильтры:

def get_profiles(text):
    qs = Profile.objects.all()
    for term in text.split():
        qs = qs.filter( Q(name__icontains = term) | Q(surname__icontains = term))
    return qs
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...