Список сущностей готов, поэтому можно переходить к просмотру каждого элемента. Начинаем с маршрутизации:
from django.urls import path
from hexlet_django_blog.article.views import IndexView, ArticleView
urlpatterns = [
path('', IndexView.as_view()),
path('<int:id>/', ArticleView.as_view()),
]
В этом месте у маршрута появляется динамическая часть — идентификатор статьи. Подобный маршрут обрабатывает все страницы, имеющие вид /articles/<идентификатор статьи>/
. Пара примеров:
/articles/1/
/articles/100/
Этот идентификатор используется в обработчике для выборки из базы нужной статьи.
from django.shortcuts import render, get_object_or_404
from django.views import View
from hexlet_django_blog.article.models import Article
class ArticleView(View):
def get(self, request, *args, **kwargs):
article = get_object_or_404(Article, id=kwargs['id'])
return render(request, 'articles/show.html', context={
'article': article,
})
Параметр id, который определен в маршруте, приходит в обработчик в kwargs. Он представляет собой словарь. Если параметров в маршруте больше одного, то они передадутся в обработчик в том же порядке, в котором они определены в маршруте:
from django.urls import path
from hexlet_django_blog.article.views import ArticleCommentsView
urlpatterns = [
...
path('<int:article_id>/comments/<int:id>/', ArticleCommentsView.as_view()),
]
# views.py
class ArticleCommentsView(View):
def get(self, request, *args, **kwargs):
comment = get_object_or_404(Comment, id=kwargs['id'], article__id=kwargs['article_id'])
return render( ... )
Затем происходит выборка статьи из базы данных. Для нее используется функция get_object_or_404
, а не get
.
Дело в том, что просмотр конкретной сущности должен вернуть ошибку 404, если самой сущности не существует. Метод get
не помогает обработать эту ситуацию, он возвращает None
. Дальше программисту придется делать проверку на существование и самому формировать правильный HTTP-ответ.
Так как задача очень частая, то разработчики Django решили ее внутри фреймворка. С одной стороны, они добавили функцию get_object_or_404
, которая выбрасывает исключение в случае отсутствия записи. С другой — добавили специальную обработку данных исключений на уровне обработки запросов.
И последний шаг — передача статьи в шаблон. Здесь ничего нового:
{% extends "base.html" %}
{% block content %}
<h1>{{ article.name }}</h1>
<div>{{ article.body }}</div>
{% endblock %}
Самостоятельная работа
- Выполните все шаги из теории
- Убедитесь, что при запросе страницы /articles/
<id>
у вас выводится конкретная статья - Сделайте имя статьи в списке статей ссылкой на конкретную статью
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.