Evgenii Legotckoi
Evgenii Legotckoi04 жовтня 2016 р. 12:09

Django - Підручник 012. Пошук по сайту з розбиттям сторінок на основі Django

Для організації пошуку на сайті, що базується на 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 хостинг.

Вам це подобається? Поділіться в соціальних мережах!

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
Г

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

  • Результат:66бали,
  • Рейтинг балів-1
t

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

  • Результат:33бали,
  • Рейтинг балів-10
t

Qt - Тест 001. Сигналы и слоты

  • Результат:52бали,
  • Рейтинг балів-4
Останні коментарі
G
GoattRock03 вересня 2024 р. 13:50
Як скопіювати файли в Linux Задумывались когда-нибудь о том, как мы привыкли доверять свои вещи службам грузоперевозок? Сейчас такие услуги стали неотъемлемой частью нашей жизни, особенно когда речь идет о переездах между …
ВР
Влад Русоков02 серпня 2024 р. 01:47
Як скопіювати файли в Linux Screenshot_20240802-065123.png
d
dblas505 липня 2024 р. 11:02
QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssr08 лютого 2024 р. 18:43
Qt Linux - Урок 001. Автозапуск програми Qt під Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий Кононенко05 лютого 2024 р. 01:50
Qt WinAPI - Урок 007. Робота з ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
Тепер обговоріть на форумі
Evgenii Legotckoi
Evgenii Legotckoi24 червня 2024 р. 15:11
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
F
Fynjy22 липня 2024 р. 04:15
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …
BlinCT
BlinCT25 червня 2024 р. 01:00
Нарисовать кривую в qml Всем привет. Имеется Лист листов с тосками, точки получаны интерполяцией Лагранжа. Вопрос, как этими точками нарисовать кривую? ChartView отпадает сразу, в qt6.7 появился новый элемент…
BlinCT
BlinCT05 травня 2024 р. 05:46
Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
Evgenii Legotckoi
Evgenii Legotckoi02 травня 2024 р. 14:07
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.

Слідкуйте за нами в соціальних мережах