Запрос полного имени в Джанго - PullRequest
21 голосов
/ 07 октября 2011

Как я могу запросить полное имя в Django?

Чтобы уточнить, я, по сути, хочу создать временный столбец, комбинируя first_name и last_name, чтобы дать полное имя, а затем сделать LIKE, например:

select [fields] from Users where CONCAT(first_name, ' ', last_name) LIKE '%John Smith%";

Приведенный выше запрос вернет всех пользователей по имени Джон Смит. Если возможно, я бы хотел избежать использования необработанного вызова SQL.

Модель, о которой я говорю, - это модель пользователя django.contrib.auth.models. Внесение изменений в модель напрямую не является проблемой.

Например, если пользователь должен искать «Джон Пол Смит», он должен сопоставлять пользователей с именем «Джон Пол» и фамилией «Смит», а также пользователей с именем «Джон» и фамилия «Пол Смит».

Ответы [ 5 ]

16 голосов
/ 30 мая 2018

Этот вопрос был опубликован давным-давно, но у меня была похожая проблема, и я нашел здесь довольно плохие ответы. Принятый ответ позволяет только найти точное совпадение по имени и фамилии. Второй ответ немного лучше, но все же плохо, потому что вы попали в базу данных столько, сколько было слов. Вот мое решение, которое объединяет first_name и last_name, комментирует его и ищет в этом поле:

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

users = User.objects.annotate(full_name=Concat('first_name', V(' '), 'last_name')).\
                filter(full_name__icontains=query)

Например, если имя человека - Джон Смит, вы можете найти его, набрав Джон Смит, Джон Смит, Хан Смит и так далее. Бьет только по базе данных. И я думаю, что это будет именно тот SQL, который вы хотели в открытом посте.

11 голосов
/ 28 июня 2013

Легче:

from django.db.models import Q 

def find_user_by_name(query_name):
   qs = User.objects.all()
   for term in query_name.split():
     qs = qs.filter( Q(first_name__icontains = term) | Q(last_name__icontains = term))
   return qs

Где query_name может быть "John Smith" (но также будет извлекать пользователя Smith John, если таковой имеется).

3 голосов
/ 07 октября 2011
class User( models.Model ):
    first_name = models.CharField( max_length=64 )
    last_name = models.CharField( max_length=64 )
    full_name = models.CharField( max_length=128 )
    def save( self, *args, **kw ):
        self.full_name = '{0} {1}'.format( first_name, last_name )
        super( User, self ).save( *args, **kw )
3 голосов
/ 07 октября 2011

Если я что-то упустил, вы можете использовать python для запроса вашей БД следующим образом:

from django.contrib.auth.models import User
x = User.objects.filter(first_name='John', last_name='Smith') 

Edit: Чтобы ответить на ваш вопрос:

Если вам нужно вернуть «John Paul Smith», когда пользователь ищет «John Smith», тогда вы можете использовать « содержит », что переводится в SQL LIKE. Если вам просто нужна возможность сохранить имя «Джон Пол», поместите оба имени в столбец first_name.

User.objects.filter(first_name__contains='John', last_name__contains='Smith') 

Это означает:

SELECT * FROM USERS
WHERE first_name LIKE'%John%' 
AND last_name LIKE'%Smith%'
0 голосов
/ 26 мая 2017

Что по этому поводу:

query = request.GET.get('query')
users = []

try:
    firstname = query.split(' ')[0]
    lastname  = query.split(' ')[1]
    users += Users.objects.filter(firstname__icontains=firstname,lastname__icontains=lastname)
    users += Users.objects.filter(firstname__icontains=lastname,lastname__icontains=firstname)

users = set(users)

Испытано и проверено!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...