На сайте присутствует функционал, благодаря которому можно задать вопрос на форуме с указанием статьи на сайте, к которой так или иначе относится данный вопрос. Это делается благодаря внешним ключам от темы на форуме сайта к статьям. При этом внешнего ключа может и не быть.
article = models.ForeignKey(Article, verbose_name=_("Статья"), null=True, blank=True)
Таким образом в конце статьи можно увидеть, сколько вопросов на форуме задано по этой статье. Это позволяет улучшить перелинковку страниц сайта, а также предоставляет пользователям возможность найти похожие вопросы относительно статьи, которую они изучают.
Главным вопросом для меня было, как реализовать список тем на форуме так, чтобы не перегружать сайт дополнительными страницами, которые бы усложнили навигацию. Решение оказалось достаточно простым: добавить возможность поиска на форуме с дополнительными расширенными ключами поиска. А именно ключ article , который определял бы id статьи, по которому нужно отфильтровать все темы на форуме, которые содержат внешний ключ на статью с данным id .
Такой подход позволил минимально изменить главную страницу форума, расширить функционал форума дополнительным поиском и исключить добавление нового представления и шаблона для новых страниц.
Шаблон
В саму вёрстку я не буду углубляться, это не настолько принципиально, покажу лишь вёрстку для формы поиска.
<form class="input-group" method="get"> <input name="q" type="text" class="form-control" placeholder="Поиск по форуму" value="{{ q }}"> <span class="input-group-btn"> <button type="submit" class="btn btn-default">Поиск</button> </span> </form> {% include 'forum/partials/index_topics_list.html' %}
Для вёрстки используется bootstrap 3 . В шаблоне главной страницы форума присутствует шаблон для вывода списка тем форума, а также форма ввода поискового запроса. В данном случае используется get метод для запроса.
Запрос может представлять собой обычное слово или словосочетание или пару ключ:значение . В данном случае пара будет выглядеть так article:95.
q - это соответственно текст поискового запроса.
В данном решении обрабатывается только одна пара ключа и значения. Этого достаточно для моих целей.
urls.py
В диспетчере путей нет ничего особенного.
# -*- coding: utf-8 -*- from django.conf.urls import url from . import views app_name = 'forum' urlpatterns = [ url(r'^$', views.IndexView.as_view(), name='index'), ]
views.py
Поиск по расширенному ключу делается через исключение, то есть если не удаётся выделить пару ключ/значение, то пытаемся использовать обычный поиск.
''' Advanced search keys ''' ARTICLE = 'article' class IndexView(View): template_name = 'forum/index.html' def get(self, request): q = self.request.GET.get('q') if q: try: # Попытаемся разбить поисковый запрос на пару ключ/значение key, value = q.split(':') # Если удалось и нет исключения, то проверяем, является ли ключ исправным, а значение является ли числом if key == ARTICLE and value.isdigit(): # если да, то то фильтруем темы по внешнему ключу статей object_list = Topic.objects.filter(article__pk=value).order_by('-lastmod') else: # в противном случае выкидываем исключение raise ValueError except ValueError: # При исключении делаем обычный поиск по заголовку тем, содержанию тем и содержанию сообщений в темах форума object_list = Topic.objects.filter( Q(title__icontains=q) | Q(content__icontains=q) | Q(forumpost__content__icontains=q) ).distinct().order_by('-lastmod') else: # если поисковый запрос отсутствует, то выполняем обычную выборку статей object_list = Topic.objects.all().order_by('-lastmod') return render( request=request, template_name=self.template_name, context={ 'q': q or '', 'object_list': get_paginated_page(request, object_list, 40), 'last_question': request.get_full_path().replace(request.path, '') # url для пагинации с учётом вопроса } )
Про функцию get_paginated_page можете прочитать в статье про перезагрузку части контента страницы .
Таким образом можно реализовать как ссылку на вопросы форума, связанные со статьей,
<a href="{% url 'forum:index' %}?q=article:{{ article.pk }}">
так и ключи расширенного поиска в стиле известных поисковых систем.
Для Django рекомендую VDS-сервера хостера Timeweb .
Добрый день!
Помогите советом: есть таблица (over 150.000 записей) по которой хотелось бы вести поиск по трем полям не усложняя жизнь пользователю вводом форматированных запросов.
Поле поиска одно, в котором пользователь может ввести как данные из одного поля, так и их сочетание.
Как-то это реализуемо или я много хочу?)