Site/blog/views.py
2026-02-25 04:23:22 +03:00

110 lines
4.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from programmer.mixins import MenuContextMixin
from django.views.generic import ListView, DetailView, CreateView
from django.urls import reverse_lazy
from django.contrib import messages
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
from .models import Article, Category
from .services import (
get_published_articles, get_article_by_slug,
increment_article_views, add_comment_to_article
)
from .forms import CommentForm
from django.http import Http404
from django.shortcuts import redirect
from django.contrib.admin.views.decorators import staff_member_required
class ArticleListView(MenuContextMixin, ListView):
"""Список статей"""
model = Article
template_name = 'blog/article_list.html'
context_object_name = 'articles'
paginate_by = 10
def get_queryset(self):
category_slug = self.kwargs.get('category_slug')
return get_published_articles(category_slug)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['categories'] = Category.objects.all()
context.update({
'title': "Статии | Инструкции",
'meta_description': (
"Инструкции по работе в 1С и бизнес-решения"
"инструкции, статьи помощь 1С."
),
'meta_keywords': (
"проекты 1С, автоматизация склада 1С, интеграция ТСД 1С, "
"миграция 1С 7.7, кейсы 1С, примеры работ 1С"
),
})
if 'category_slug' in self.kwargs:
context['current_category'] = Category.objects.filter(
slug=self.kwargs['category_slug']
).first()
return context
@method_decorator(cache_page(60 * 5)) # кэширование страницы на 5 минут
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
class ArticleDetailView(MenuContextMixin, DetailView, CreateView):
"""Детальная страница статьи + форма комментария"""
model = Article
template_name = 'blog/article_detail.html'
context_object_name = 'article'
form_class = CommentForm
def get_object(self, queryset=None):
article = get_article_by_slug(self.kwargs['slug'])
if article is None:
raise Http404("Статья не найдена")
return article
def get(self, request, *args, **kwargs):
# Увеличиваем счётчик просмотров при GET запросе
self.object = self.get_object()
increment_article_views(self.object)
return super().get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def get_initial(self):
"""Возвращает пустые начальные данные для формы комментария."""
initial = super().get_initial()
initial['content'] = ''
return initial
def form_valid(self, form):
comment = add_comment_to_article(
article=self.object,
data=form.cleaned_data
)
messages.success(self.request, "Ваш комментарий отправлен на модерацию.")
return redirect(self.object.get_absolute_url())
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# Добавляем только одобренные комментарии
context['moderated_comments'] = self.object.comments.filter(is_moderated=True)
return context
@method_decorator(staff_member_required, name='dispatch')
class ArticleDraftPreviewView(DetailView):
model = Article
template_name = 'blog/article_detail.html' # используем тот же шаблон
context_object_name = 'article'
def get_queryset(self):
# Для предпросмотра показываем даже неопубликованные статьи
return Article.objects.all() # без фильтрации по is_published