Фильтр объектов Django для поиска как уникальных, так и комбинированных полей с эксклюзивностью

Я пытаюсь создать функцию поиска для набора запросов Django, которая могла бы искать по уникальным ключевым словам, но при этом иметь эксклюзивность.

Например, если я ищу "John", я хочу, чтобы мне вернули всех Джонов, если я ищу "Smith", я хочу, чтобы вернули всех Смитов, но если я ищу "John Smith", я хочу, чтобы вернули только "John Smith(s)".

Я пробовал несколько методов:

Попытка 1 - views.py

Это возвращает только результаты с идентичным ключевым словом. т.е. возвращает все John's или только Smith's, но поиск John Smith ничего не возвращает:

if query:
    data = Profile.objects.filter(
        Q(first_name__icontains=query) | Q(last_name__icontains=query) |
        Q(username__username__icontains=query) | Q(email__icontains=query) |
        Q(telephone__icontains=query) | Q(mobile__icontains=query) |
        Q(job_title__icontains=query) | Q(department__icontains=query) |
        Q(address__address__icontains=query)
    ).distinct()

Попытка 2 - views.py

Это возвращает всех Джонов и Смитов, а поиск Джона Смита по-прежнему возвращает всех Джонов и Смитов.

if query:
    search = []
    query_set = query.split()
    for word in query_set:
    search = Profile.objects.filter(
            Q(first_name__icontains=word) | Q(last_name__icontains=word) |
            Q(username__username__icontains=word) | Q(email__icontains=word) |
            Q(telephone__icontains=word) | Q(mobile__icontains=word) |
            Q(job_title__icontains=word) | Q(department__icontains=word) |
            Q(address__address__icontains=word)
        ).distinct()
    data = list(set(search))

Есть ли идеи, как это решить?

Вы осуществляете поиск, используя __icontains в своем фильтре. Это вернет все объекты, содержащие указанную вами строку, без учета регистра. Таким образом, John вернет true для John, john, JoHn, John Smith, Johnny или любого объекта, содержащего любую версию John.

Вам необходимо реализовать отдельный запрос, использующий __exact или __iexact. Это даст вам искомый эксклюзивный поиск. Так, если вы ищете John Smith, используя __exact__, будут возвращены только объекты с John Smith, с учетом регистра. Если вы используете __iexact__, Джон Смит, Джон Смит, Джон Смит или любой объект, содержащий Джон Смит, независимо от регистра, вернет True. Johnny Smith не вернет True ни для одного из запросов __exact__ или __iexact в данном случае.

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

Таким образом, ваш запрос изменится с Q(first_name__icontains=word) на Q(first_name__exact=word) или Q(first_name__iexact=word).

Вернуться на верх