Евгений Легоцкой4 октября 2016 г. 12:09

Django - Урок 012. Внедрение поиска по сайту с пагинацией результатов

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

Но для того, чтобы выдача поисковых запросов походила больше на главную страницу, добавим возможность пагинации страниц выдачи, а результаты будут выводиться по 10 штук на одной странице. И для этого также будем использовать модуль django_bootstrap3.

В итоге имеем следующий план действий:

  1. Добавляем приложение для организации поиска;
  2. Добавляем url поиска;
  3. Добавляем форму поиска;
  4. Описываем шаблон страницы поиска.
  5. Описываем представление для обработки выдачи поиска;

Добавляем приложение для поиска

Стандартный момент по созданию нового приложения в вашем проекте Django:

python manage.db startapp search

На выходе получим новое приложение со следующей структурой:

search/
    migrations/
        \_\_init\_\_.py
    \_\_init\_\_.py
    admin.py
    apps.py
    models.py
    tests.py
    views.py

Подкорректируем немного файл settings.py . Добавим конфигурацию нашего приложения, используется та, что создастся по умолчанию, также воспользуемся двумя модулями:

  1. Для работы с postgres
  2. django_bootstrap3
INSTALLED\_APPS = [
    ...
    'search.apps.SearchConfig',
    'django.contrib.postgres',
    'bootstrap3',
    ...
]

Добавляем urls поиска

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

from django.conf.urls import url, include

urlpatterns = [
    ...
    url(r'^search/', include('search.urls')),
]

Во-вторых, нужно добавить urls.py файл в само приложение search со следующим содержимым, чтобы настроить отправку запроса в представление.

from django.conf.urls import url

from . import views

app\_name = 'search'
urlpatterns = [
    url(r'^$', views.ESearchView.as\_view(), name='index'),
]

Форма поиска

Форма поиска добавлена в базовый шаблон base.html в приложении home , который будет наследоваться шаблоном страницы поиска.

Приведу тот вариант, который используется на данном сайте с использованием django-bootstrap3

{% load bootstrap3 %}
<form action="{% url 'search:index' %}" class="navbar-form navbar-left" method="get">
    <div class="input-group">
        <input id="search" name="q" type="text" class="form-control" placeholder="Поиск">
        <span class="input-group-btn">
            <button type="submit" class="btn btn-default">{% bootstrap\_icon 'search' %}</button>
        </span>
    </div>
</form>

Разберёмся в ключевых моментах:

  1. В поле action указан адрес куда будет посылаться запрос;
  2. Будет использоваться метод GET, поскольку пользователь может захотеть поделиться результатом поиска;
  3. bootstrap_icon подгружает иконки из набора glyphicons.

Шаблон страницы поиска

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

Но самым главным отличием от главной страницы является то, что каким-то образом необходимо совместить перелистывание страниц при пагинации и сохранение запроса. Для этого можно подставлять кастомизированный URL в bootstrap_pagination. А именно url=last_question, который будет содержать последний запрос, который был задан в форме поиска. К этому URL автоматически будет добавлен номер страницы.

{% extends 'home/base.html' %}
{% load bootstrap3 %}
{% block page %}
    <h1>Поиск</h1>
    {% if article\_lists %}
        {% for article in article\_lists %}
            <article>
                <a href="{{ article.get\_absolute\_url }}">
                    <h2>{{ article.article\_title }}</h2>
                </a>
                {{ article.desctription|safe }}
                <p><a class="btn btn-default btn-sm" href="{{ article.get\_absolute\_url }}">Читать далее</a></p>
            </article>
        {% endfor %}
        {% bootstrap\_pagination article\_lists url=last\_question %}
    {% else %}
        <p>Не найдено публикаций по вашему запросу<br>Попробуйте повторить запрос с другой формулировкой</p>
    {% endif %}
{% endblock %}

Представление поиска

Важным моментом является здесь то, что из запроса необходимо подготовить URL, который будет содержать последний запрос и подставляться в кнопочки пагинации. Иначе при нажатии кнопки пагинации поиск будет ошибочен и скорее всего будете получать ошибку 500 .

from django.shortcuts import render\_to\_response
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.views import View

from knowledge.models import Article


class ESearchView(View):
    template\_name = 'search/index.html'

    def get(self, request, *args, **kwargs):
        context = {}

        question = request.GET.get('q')
        if question is not None:
            search\_articles = Article.objects.filter(article\_content\_\_search=question)

            # формируем строку URL, которая будет содержать последний запрос
            # Это важно для корректной работы пагинации
            context['last\_question'] = '?q=%s' % question

            current\_page = Paginator(search\_articles, 10)

            page = request.GET.get('page')
            try:
                context['article\_lists'] = current\_page.page(page)
            except PageNotAnInteger:
                context['article\_lists'] = current\_page.page(1)
            except EmptyPage:
                context['article\_lists'] = current\_page.page(current\_page.num\_pages)

        return render\_to\_response(template\_name=self.template\_name, context=context)

Для Django рекомендую VDS-сервера хостера Timeweb .

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.
Поддержать автора Donate

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
Card image cap
Pulsum Via

Проект для путешественников от EVILEG.

Перейти
Timeweb

Позвольте мне порекомендовать вам отличный хостинг, на котором расположен EVILEG.

В течение многих лет Timeweb доказывает свою стабильность.

Для проектов на Django рекомендую VDS хостинг

Посмотреть Хостинг
Поделиться в социальных сетях
Donate

Проект EVILEG перешёл на некоммерческую основу и будет развиваться исключительно на энтузиазме создателя сайта, энтузиазме пользователей, пожертвованиях и реферальной системе хостинга

Спасибо за вашу поддержку

Доступные способы поддержки проекта

PayPal

PatreonYooMoneyПодробнее

C++ - Тест 001. Первая программа и типы данных

  • Результат:80баллов,
  • Очки рейтинга4

C++ - Тест 001. Первая программа и типы данных

  • Результат:66баллов,
  • Очки рейтинга-1
ГР

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:90баллов,
  • Очки рейтинга8
Последние комментарии

Qt/C++ - Урок 061. Добавление изображений в приложение методом Drag And Drop из файлового менеджера

Доброго времени суток. А если нужно и изображение и текст? Что-то потерялся немного.... // Вместо отрисовки иконки и текста будем отрисовывать только одно изображение // с н…
АС

Qt/C++ - Урок 004. QSqlTableModel или Как представить таблицу из БД в Qt?

error insert into TableExample " Количество параметров не совпадает" Я путь свой прописывала и даже бд удаляла, чтобы заново сделать, не работает. (всё остальное как у вас... Вроде ка…
i
ЛД

GameDev на Qt - Урок 1. Отслеживание перемещения мыши в QGraphicsScene

Вполне возможно, что ты не закинул graphicsView в дизайнере в виджет
ЛД

GameDev на Qt - Урок 1. Отслеживание перемещения мыши в QGraphicsScene

Кому интересно, поворот в slotTarget можно в одну строку организовать this->setRotation(90 + rotation() + qRadiansToDegrees(qAtan2(mapFromScene(point).y(), mapFromScene(point).x())));
Сейчас обсуждают на форуме
M

Sorting the added QML elements in the ListModel

legal online pharmacy
  • Nomad
  • 30 июля 2022 г. 5:42

Как работать с HTMX?

Приветствую колеги. На днях наткнулся на вот это : https://htmx.org/ На офф сайте написанно вот такая фраза: htmx gives you access to AJAX, CSS Transitions, We…
h
  • harisr
  • 25 июля 2022 г. 2:56

QT - Native App Integration

Привет, у нас уже есть собственное приложение для Android. Можем ли мы интегрировать пользовательское представление QT в приложение со всем приложением QT внутри представления. Если да, ука…

Правильный запуск сервера на vps - Django

О я как то себе дома локальный сервер создавал. Вам же нужно просто сделать ручками конфигурацию системы. Настроить Nginx ну либо Apache (тут кому что нравится). Соответственно БД и всё остально…
o

Распознание объектов

Я к тому, что, возможно, софт уже есть.
О нас
Услуги
© EVILEG 2015-2022
Рекомендует хостинг TIMEWEB