Разработка представления поиска
Теперь вы создадите конкретно-прикладное представление, позволяющее пользователям выполнять поиск постов. Прежде всего понадобится форма для поиска.
Отредактируйте файл forms.py приложения blog, добавив следующую ниже форму:
class SearchForm(forms.Form):
query = forms.CharField()
Поле запроса будет использоваться для того, чтобы давать пользователям возможность вводить поисковые запросы.
Отредактируйте файл views.py приложения blog, добавив следующий ниже исходный код:
# ...
from django.contrib.postgres.search import SearchVector
from .forms import EmailPostForm, CommentForm, SearchForm
# ...
def post_search(request):
form = SearchForm()
query = None
results = []
if 'query' in request.GET:
form = SearchForm(request.GET)
if form.is_valid():
query = form.cleaned_data['query']
results = Post.published.annotate(
search=SearchVector('title', 'body'),
).filter(search=query)
return render(request,
'blog/post/search.html',
{'form': form,
'query': query,
'results': results})
В приведенном выше представлении сначала создается экземпляр формы SearchForm.
Для проверки того, что форма была передана на обработку, в словаре request.GET отыскивается параметр query.
Форма отправляется методом GET, а не методом POST, чтобы результирующий URL-адрес содержал параметр query и им было легко делиться.
После передачи формы на обработку создается ее экземпляр, используя переданные данные GET, и проверяется валидность данных формы.
Если форма валидна, то с помощью конкретно-прикладного экземпляра SearchVector, сформированного с использованием полей title и body, выполняется поиск опубликованных постов.
Теперь представление поиска готово и необходимо создать шаблон отображения формы и результатов при выполнении пользователем поиска.
Внутри каталога templates/blog/post/ создайте новый файл, назовите его search.html и добавьте в него следующий ниже исходный код:
{% extends "blog/base.html" %} {% load blog_tags %}
{% block title %}Search{% endblock %}
{% block content %} {% if query %}
<h1>
Posts containing "{{ query }}"
</h1>
<h3>
{% with results.count as total_results %}
Found {{ total_results }} result{{ total_results|pluralize }} {% endwith %}
</h3>
{% for post in results %}
<h4>
<a href="{{ post.get_absolute_url }}"> {{ post.title }}
</a>
</h4>
{{ post.body|markdown|truncatewords_html:12 }} {% empty %}
<p>There are no results for your query.</p>
{% endfor %}
<p><a href="{% url 'blog:post_search' %}">Search again</a></p> {% else %}
<h1>
Search for posts
</h1>
<form method="get">
{{ form.as_p }}
<input type="submit" value="Search">
</form>
{% endif %} {% endblock %}
Как и в представлении поиска, по наличию параметра query определяется, что форма была передана на обработку.
Перед передачей запроса мы отображаем форму и кнопку передачи формы.
После передачи формы поиска на обработку отображается выполненный запрос, общее число результатов и список постов, совпадающих с поисковым запросом.
Наконец, отредактируйте файл urls.py приложения blog, добавив следующий ниже шаблон URL-адреса:
urlpatterns = [
# представления поста
path('', views.post_list, name='post_list'),
# path('', views.PostListView.as_view(), name='post_list'),
path('tag/<slug:tag_slug>/',
views.post_list, name='post_list_by_tag'),
path('<int:year>/<int:month>/<int:day>/<slug:post>/',
views.post_detail, name='post_detail'),
path('<int:post_id>/share/', views.post_share, name='post_share'),
path('<int:post_id>/comment/', views.post_comment, name='post_comment'),
path('search/', views.post_search, name='post_search'),
]
Далее пройдите по URL-адресу http://127.0.0.1:8000/blog/search/ в своем браузере. Вы должны увидеть следующую ниже форму для поиска:
Введите запрос и кликните по кнопке SEARCH(Найти). Вы увидите результаты поискового запроса, как показано ниже:
Поздравляю! Вы создали базовый поисковый механизм для своего блога.