Блог на Django #33: Добавление поиска по блогу

Добавим поисковые возможности в блог. Django ORM позволяет проводить базовые операции по поиску совпадений с помощью, например, фильтра contains (или его версии, учитывающей регистр, icontains). Следующий запрос можно использовать для поиска постов, содержащих слово framework в теле:

from blog.models import Post Post.objects.filter(body__contains='framework')

Но если планируется осуществлять сложный поиск с получением результатов, учитывающих схожесть или разный вес у полей, потребуется полнотекстовый поисковый движок.

Django предлагает мощный поиск, созданный на основе полнотекстового поиска из PostgreSQL. Модуль django.contrib.postgres включает функции, которые есть в PostgreSQL, но которых лишены другие базы данных, поддерживаемые Django. Больше об этом поиске можно узнать здесь: https://www.postgresql.org/docs/10/static/textsearch.html.

Хотя Django и способен работать с любой базой данных, он включает модуль, поддерживающий широкий набор возможностей из PostgreSQL, которых нет в других базах данных, поддерживаемых Django.

Простой поиск

Отредактируйте файл settings.py проекта и добавьте в пункт INSTALLED_APP строку django.contrib.postgres:

INSTALLED_APPS = [ 
    # ... 
    'django.contrib.postgres', 
]

Теперь с помощью search можно проводить поиск:

from blog.models import Post Post.objects.filter(body__search='django')

Этот запрос использует PostgreSQL для создания направления поиска поля body и поискового запроса «django». Результаты основаны на сопоставлении направления и запроса.

Поиск в нескольких полях

Иногда может потребоваться искать в нескольких полях. В этом случае нужно определить SearchVector. Построим вектор, который позволит искать в полях title и body модели Post:

from django.contrib.postgres.search import SearchVector 
from blog.models import Post 

Post.objects.annotate( 
    search=SearchVector('title', 'body'), 
).filter(search='django')

С помощью annotate и SearchVector для обоих полей получается функциональность, которая будет искать совпадения в заголовке и теле постов.

Полнотекстовый поиск — это интенсивный процесс. Если он будет осуществляться в более чем нескольких сотнях строк, нужно определить функциональный индекс, который совпадает с используемым поисковым направлением. Django предлагает поле SearchVectorField для моделей. Подробно об этом можно почитать здесь: https://docs.djangoproject.com/en/2.0/ref/contrib/postgres/search/#perfomance.

Появились вопросы? Задайте на Яндекс Кью

У блога есть сообщество на Кью >> Python Q <<. Там я и другие участники отвечаем на вопросы по python, программированию и контенту сайта.

Обучение Python и Data Science

Профессия Data Scientist

Профессия Data Scientist

11 800 5 900 ₽/мес.
Профессия Python-разработчик

Профессия Python-разработчик

9 800 4 900 ₽/мес.
Профессия Python Fullstack

Профессия Python Fullstack

7 800 3 900 ₽/мес.
Курс Аналитик данных с нуля

Курс Аналитик данных с нуля

6 500 3 900 ₽/мес.

Вам помогла эта статья? Поделитесь в соцсетях или блоге. Репосты помогают сайту развиться.