From 626bf19a9ebb826580b718c02faa72bb47f55f21 Mon Sep 17 00:00:00 2001 From: erjemin Date: Sun, 9 Aug 2026 23:23:12 +0300 Subject: [PATCH] =?UTF-8?q?add:=20=D1=80=D0=BE=D1=83=D1=82=20=D0=B8=20?= =?UTF-8?q?=D0=B2=D1=8C=D1=8E=D1=85=D0=B0=20=D0=B4=D0=BB=D1=8F=20HUB=20(?= =?UTF-8?q?=D0=B4=D1=80=D0=B0=D1=84=D1=82=201)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lpon_site/frontend/views.py | 57 +++++++++++++++++++++++++++++++++++-- lpon_site/lpon_site/urls.py | 3 ++ 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/lpon_site/frontend/views.py b/lpon_site/frontend/views.py index aebce3b..e486f50 100644 --- a/lpon_site/frontend/views.py +++ b/lpon_site/frontend/views.py @@ -2,8 +2,8 @@ from dataclasses import dataclass -from django.shortcuts import render, get_object_or_404 -from django.http import HttpRequest, HttpResponse +from django.shortcuts import render, get_object_or_404, redirect +from django.http import HttpRequest, HttpResponse, Http404 from frontend.models import TbArticle @@ -197,4 +197,55 @@ def info_article_detail(request: HttpRequest | None, slug: str) -> HttpResponse: "article": article, "breadcrumbs": breadcrumbs, } - return render(request, "content/article_detail.html", context) \ No newline at end of file + return render(request, "content/article_detail.html", context) + + +def hub_detail(request: HttpRequest, slug: str) -> HttpResponse: + """ + Универсальное представление (View) для хабов (включая страницы, запрашиваемые из корня сайта /). + + Функциональность: + ----------------- + 1. Ищет опубликованную статью (b_article_published=True) по её слагу (slug). + 2. Если статья принадлежит к каноническому типу с отдельным роутом (например, ArticleType.INFO), + выполняет HTTP 301 Permanent Redirect на её канонический адрес (/info//). + 3. Если статья не найдена — отдаёт честный HTTP 404 status (с отображением страницы 404, + где для авторизованного администратора request.user.is_staff выводится блок-подсказка). + 4. Увеличивает счётчик просмотров статьи, формирует хлебные крошки и рендерит шаблон хаба. + + Аргументы: + request (HttpRequest): Объект HTTP-запроса Django. + slug (str): Уникальный URL-слаг хаба или страницы. + + Возвращает: + HttpResponse: Сформированная HTML-страница хаба либо страница ошибки 404. + """ + # Ищем опубликованную статью по запрошенному слагу + article = TbArticle.objects.filter( + slug=slug, + b_article_published=True, + ).first() + + # Если статья не найдена — отдаём честный статус 404 + if not article: + return render(request, "404.html", {"requested_slug": slug}, status=404) + # Если нашлась статья с таким слагом и она не HUB, то делаем канонический 301-редирект на собственную ветку роутинга + # Предполагается, что у всех статей с типом ArticleType.INFO, ArticleType.TXT и т.д. есть роутинг в urls.py + elif article and article.l_article_type != TbArticle.ArticleType.HUB: + return redirect(article.get_absolute_url(), permanent=True) + + # Это статья-ХАБ!! ТУТ будет сложный код, над которым я думаю. + context = {} + pass + + # Формирование хлебных крошек + # article_title = article.s_article_title_html or article.s_article_title + # breadcrumbs = [ + # BreadcrumbItem(title=article_title), + # ] + # + # context = { + # "article": article, + # "breadcrumbs": breadcrumbs, + # } + return render(request, "content/hub.html", context) \ No newline at end of file diff --git a/lpon_site/lpon_site/urls.py b/lpon_site/lpon_site/urls.py index 0cd55e1..b171319 100644 --- a/lpon_site/lpon_site/urls.py +++ b/lpon_site/lpon_site/urls.py @@ -29,6 +29,9 @@ urlpatterns = [ re_path(r'^catalog/$', views.catalog), re_path(r'^info/?$', views.info_articles_list, name='info_articles_list'), re_path(r'^info/(?P[-a-zA-Z0-9_]+)/?$', views.info_article_detail, name='info_article_detail'), + + # Универсальный роут для хабов и страниц из корня (должен идти ПОСЛЕДНИМ!) + re_path(r'^(?P[-a-zA-Z0-9_]+)/?$', views.hub_detail, name='hub_detail'), ] # Сервировать медиа-файлы в разработке (в production использовать nginx/Apache)