Для удобства принято при выводе на экран разбивать объявления по рубрикам. Добавим на страницу панель навигации со списком рубрик. При выборе определенной рубрики на страницу будут выводится только объявления, которые к ней относятся.
Чтобы контроллер, отвечающий за вывод объявлений, мог смог их отфильтровать, ему необходимо передать ключ рубрики. Сделать это можно через GET-параметр, например, по такому шаблону: /bboard/?rubric=<ключ>.
Однако Django позволяет размещать параметр непосредственно в состав URL: bboard/<ключ>/ (URL-параметр).
В этом случае необходимо указать маршрутизатору, какая часть адреса является URL-параметром. Также указывается тип значения и имя параметра, которому будет присвоено извлеченное значение. Откроем urls.py приложения bboard и внесем правки:
. . . from .vews import index, by_rubric urlpatterns = [ path('<int:rubric_id>', by_rubric), path('', index), ]
В набор маршрутов добавлена строка с путем <int:rubric_id>/. Угловые скобки помечают расположение URL=параметра, конструкция int указывает на тип параметра (целочисленный), rubric_id – имя параметра контроллера, который получит значение. Созданному маршруту будет сопоставлен контроллер-функция by_rubric (описан ниже).
При получении запроса с адресом http://localhost:8000/bboard/2/, выделит часть URL bboard/2/, далее удалит префикс bboard и определит, что полученный путь соответствует первому маршруту в списке. После этого будет запущен контроллер by_rubric, в качестве параметра ему будет передан ключ рубрики.
Маршруты, которые содержат URL-параметры, называют параметризированными.
Теперь необходимо открыть модуль views.py и дописать код контроллера-функции:
from .models import Rubric def by_rubric(request, rubric_id): bbs = Bb.objects.filter(rubric=rubric_id) rubrics = Rubric.objects.all() current_rubric = Rubric.objects.get(pk=rubric_id) context = {'bbs': bbs, 'rubrics': rubrics, 'current_rubrics': current_rubrics} return render(request, 'bboard/by_rubric.html', context)
В объявлении функции был добавлен параметр rubric_id – ему будет присвоено содержимое URL-параметра, выделенное из интернет-адреса. В контекст шаблона добавлен список объявлений (фильтрация по внешнему ключу rubric), перечень всех доступных рубрик и текущую рубрику, чтобы вывести ее название.
В каталоге temptlates\bboard создадим шаблон by_rubric.html:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>{{ current_rubric.name }} :: Доска объявлений</title> </head> <body> <h1>Объявления</h1> <h2>Рубрика: {{ current_rubric.name }} </h2> <div> <a href="/bboard/">Главная</a> {% for rubric in rubrics %} <a href="/bboard/"{{ rubric.pk }}/">{{ rubric.name }}</a> {% endfor %} </div> {% for bb in bbs %} <div> <h2>{{ bb.title }}</h2> <p>{{ bb.content }}</p> <p>{{ bb.published|date:"d.m.Y H:i:s" }}</p> </div> {% endfor %} </body> </html>
Обратите внимание, каким образом формируются интернет адреса отдельных рубрик.
Отредактируем шаблон bboard\index.html и контроллер index() таким образом, чтобы панель навигации также выводилась и на главной странице. Также сделаем так, чтобы рядом с каждым объявлением выводилось название его рубрики, выполненное в виде полноценной гиперссылки. Обновленный код контролера index():
def index(request): bbs = Bb.objects.all() rubrics = Rubric.objects.all() context = {'bbs': bbs, 'rubrics': rubrics} return render(request, 'bboard/index.html', context)
Код обновленного шаблона bboard\index.html с рубриками и панелью навигации:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Главная :: Доска объявлений</title> </head> <body> <h1>Объявления</h1> <div> <a href="/bboard/">Главная</a> {% for rubric in rubrics %} <a href="/bboard/"{{ rubric.pk }}/">{{ rubric.name }}</a> {% endfor %} </div> {% for bb in bbs %} <div> <h2>{{ bb.title }}</h2> <p>{{ bb.content }}</p> <p><a href="/bboard/{{ bb.rubric.pk }}/"> {{ bb.rubric.name }}</a></p> <p>{{ bb.published|date:"d.m.Y H:i:s" }}</p> </div> {% endfor %} </body> </html>
После сохранения всех файлов и запуска отладочного веб-сервера проверим, как теперь отображается главная страница. Должна появиться панель навигации, расположенная сразу под заголовком, а также ссылки на рубрики. При переходе по такой ссылке откроется страница со списком соответствующих объявлений.