Задайте поля поиска с помощью параметра запроса

REST-фреймворк Django обеспечивает функциональность поиска из коробки.

Поиск можно выполнить, выполнив три шага:

  • Установка search_fields в классе
  • Установка filter_backends в классе
  • Отправка search параметра запроса в запросе

search указывает шаблон, который необходимо сопоставить. search_fields укажите столбцы базы данных, по которым должен быть сопоставлен шаблон.

Поведение DRF по умолчанию работает со статическим search_fields.

В этой статье мы обсуждаем ограничения статического search_fields и то, как сделать search_fields динамическим.

Полезность

Возможность динамического поиска в серверной части позволит пользователям выполнять более детальный поиск.

Это пригодится в сценарии, когда ваш внешний интерфейс перечисляет все поля / столбцы модели и позволяет пользователям выбирать поля, по которым должен быть сопоставлен шаблон.

Пользователи также смогут выбрать тип соответствия. Пользователи могут выбрать LIKE соответствие, exact соответствие или starts with соответствие.

Настраивать

В этом посте мы будем использовать следующие модели:

Статический поиск

Давайте сначала применим поиск к статическим полям, а затем сделаем поля поиска динамическими.

Давайте добавим представление, сериализатор и шаблон URL.

Благодаря этому мы сможем получить все вопросы. Функция поиска пока не добавлена.

Попробуйте отправить шаблон, скажем Samsung, в качестве параметра поискового запроса. search параметр запроса не влияет на возвращаемый ответ. Вопросы без шаблона Samsung также возвращаются в ответе.

Давайте добавим в представление функцию поиска.

Когда мы отправляем шаблон в параметре запроса GET, мы хотим, чтобы термин сопоставлялся со столбцом question_text. Для этого нам нужно добавить search_fields и filter_backends.

Давай сделаем запрос еще раз. Мы будем получать только вопросы с Samsung в question_text.

Автор этого вопроса charles.

Давайте отправим charles в качестве шаблона поиска в GET запросе и посмотрим, получим ли мы такой же ответ.

Мы не получили в ответ ожидаемого вопроса, потому что мы не настроили наше представление на соответствие шаблону столбцу author.

Мы можем добиться этого, добавив author к search_fields.

search_fields = ['question_text', 'author']

Проблемы с этим подходом

Мы добавили question_text, а также author в search_fields.

Мы хотим найти вопросы, написанные charles. Предположим, что есть вопрос, созданный tolkien, с текстом: "Do you love charles novels?"

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

Этот вопрос возник из-за того, что термин charles появляется в question_text.

Лучший подход

Лучшим подходом было бы позволить конечным пользователям указывать поля, в которых они хотят сопоставить шаблон. По сути, мы хотим сделать поля динамическими.

Для этого нам нужно создать собственный фильтр. Этот бэкэнд будет расширяться от DRF SearchFilter и переопределять метод get_search_fields().

Давайте установим этот фильтр как filter_backends представления и удалим статический search_fields из представления.

Теперь мы можем сделать запрос с шаблоном как charles и search_fields как author.

Мы используем getlist() от Django. Это позволяет нам указать несколько полей в качестве search_fields параметров запроса.

Теперь мы хотим, чтобы charles просматривался в столбцах author и question_text. Давайте отправим question_text, а также author в параметре запроса search_fields.

Спасибо за прочтение!

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

Свяжись со мной в Твиттере, я чирикаю информативные статьи и советы по программированию.