add: роутинг и шаблон для раздела "информация" (список).
This commit is contained in:
@@ -5,6 +5,8 @@ from dataclasses import dataclass
|
|||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse
|
||||||
|
|
||||||
|
from frontend.models import TbArticle
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
|
|
||||||
@@ -106,3 +108,46 @@ def catalog(request: HttpRequest | None) -> HttpResponse:
|
|||||||
BreadcrumbItem(title="Для перезаписи" ), # url передан -> обычный пункт со ссылкой
|
BreadcrumbItem(title="Для перезаписи" ), # url передан -> обычный пункт со ссылкой
|
||||||
]
|
]
|
||||||
return render(request, 'catalog.html', {"breadcrumbs": breadcrumbs})
|
return render(request, 'catalog.html', {"breadcrumbs": breadcrumbs})
|
||||||
|
|
||||||
|
|
||||||
|
def txt_articles_list(request: HttpRequest | None) -> HttpResponse:
|
||||||
|
"""
|
||||||
|
Представление (View) для отображения списка текстовых статей (тип ArticleType.TXT).
|
||||||
|
|
||||||
|
Функциональность:
|
||||||
|
-----------------
|
||||||
|
1. Выбирает из БД все опубликованные статьи (b_article_published=True) с типом 'txt'.
|
||||||
|
2. Сортирует их по полю приоритета i_article_sort (по возрастанию, чем меньше число —
|
||||||
|
тем выше в списке), затем по дате создания (-t_article_created) и названию.
|
||||||
|
3. Оптимизирует выборку связанного файла обложки (k_article_to_image) через select_related,
|
||||||
|
чтобы избежать N+1 запросов при рендеринге изображений в списке.
|
||||||
|
4. Формирует хлебные крошки (BreadcrumbItem) с элементом "Инструкции".
|
||||||
|
5. Рендерит шаблон `txt_list.html`, передавая в контекст список статей и хлебные крошки.
|
||||||
|
|
||||||
|
Аргументы:
|
||||||
|
request (HttpRequest | None): Объект HTTP-запроса Django.
|
||||||
|
|
||||||
|
Возвращает:
|
||||||
|
HttpResponse: Сформированная HTML-страница со списком текстовых статей.
|
||||||
|
"""
|
||||||
|
# Выбираем опубликованные текстовые статьи из базы данных с правильной сортировкой
|
||||||
|
articles = (
|
||||||
|
TbArticle.objects.filter(
|
||||||
|
l_article_type=TbArticle.ArticleType.TXT,
|
||||||
|
b_article_published=True,
|
||||||
|
)
|
||||||
|
.select_related('k_article_to_image')
|
||||||
|
.order_by('i_article_sort', '-t_article_created', 's_article_title')
|
||||||
|
)
|
||||||
|
|
||||||
|
# Формируем цепочку хлебных крошек (пункт "Главная" добавляется автоматически в шаблоне)
|
||||||
|
breadcrumbs = [
|
||||||
|
BreadcrumbItem(title="Инструкции"),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Передаём контекст в шаблон списка текстовых статей
|
||||||
|
context = {
|
||||||
|
"articles": articles,
|
||||||
|
"breadcrumbs": breadcrumbs,
|
||||||
|
}
|
||||||
|
return render(request, "roll/txt_list.html", context)
|
||||||
@@ -27,6 +27,7 @@ urlpatterns = [
|
|||||||
|
|
||||||
re_path(r'^$', views.index),
|
re_path(r'^$', views.index),
|
||||||
re_path(r'^catalog/$', views.catalog),
|
re_path(r'^catalog/$', views.catalog),
|
||||||
|
re_path(r'^info/?$', views.txt_articles_list, name='txt_articles_list'),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Сервировать медиа-файлы в разработке (в production использовать nginx/Apache)
|
# Сервировать медиа-файлы в разработке (в production использовать nginx/Apache)
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
{% extends "_base.html" %}{% load static %}
|
||||||
|
|
||||||
|
{% block PAGE_TITLE %}Инструкции — LPON.RU{% endblock %}
|
||||||
|
{% block DESCRIPTION %}Информационные и текстовые материалы, правила, условия и справка LPON.RU{% endblock %}
|
||||||
|
|
||||||
|
{% block CONTENT %}
|
||||||
|
{# Подключение блока хлебных крошек #}
|
||||||
|
{% include "block/breadcrumbs.html" %}
|
||||||
|
|
||||||
|
<div class="py-6">
|
||||||
|
{# Заголовок страницы #}
|
||||||
|
<h1 class="text-3xl font-bold mb-6 text-slate-900 dark:text-slate-100 font-serif px-4">
|
||||||
|
Инструкции
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
{# Список статей #}
|
||||||
|
{% if articles %}
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
|
{% for article in articles %}
|
||||||
|
<article class="flex flex-col bg-slate-50 dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-xl p-5 hover:shadow-md transition-shadow">
|
||||||
|
{# Изображение обложки, если есть #}
|
||||||
|
{% if article.k_article_to_image %}
|
||||||
|
<div class="mb-4 overflow-hidden rounded-lg max-h-48 flex items-center justify-center bg-slate-200 dark:bg-slate-800">
|
||||||
|
<img
|
||||||
|
src="{{ article.k_article_to_image.url }}"
|
||||||
|
alt="{{ article.k_article_to_image.default_alt_text|default:article.s_article_title }}"
|
||||||
|
class="w-full h-auto object-cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# Заголовок статьи со ссылкой #}
|
||||||
|
<h2 class="text-xl font-semibold mb-2 text-slate-900 dark:text-slate-100 font-serif">
|
||||||
|
<a href="/{{ article.slug }}/">
|
||||||
|
{% if article.s_article_title_html %}
|
||||||
|
{{ article.s_article_title_html|safe }}
|
||||||
|
{% else %}
|
||||||
|
{{ article.s_article_title }}
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
{# Тизер / анонс статьи #}
|
||||||
|
{% if article.s_article_teaser_html %}
|
||||||
|
<div class="text-slate-600 dark:text-slate-400 mb-4 grow leading-relaxed font-serif">
|
||||||
|
{{ article.s_article_teaser_html|safe }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# Подвал карточки с датой и кнопкой перехода #}
|
||||||
|
<div class="mt-auto pt-4 border-t border-slate-200/60 dark:border-slate-800 flex items-center justify-between text-sm text-slate-500 dark:text-slate-400 font-serif">
|
||||||
|
<span>{{ article.t_article_created|date:"Y.m.d" }}</span>
|
||||||
|
<a href="/{{ article.slug }}/" class="font-medium">
|
||||||
|
Читать полностью →
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
{# Сообщение, если опубликованных статей типа TXT пока нет #}
|
||||||
|
<div class="p-8 text-center bg-slate-50 dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-slate-800">
|
||||||
|
<p class="text-slate-600 dark:text-slate-400">
|
||||||
|
Пока нет опубликованных текстовых материалов.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endblock CONTENT %}
|
||||||
Reference in New Issue
Block a user