Files
server/front/views.py
T

262 lines
8.9 KiB
Python

import traceback
from typing import Dict, List
from unicodedata import category
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.db.models import Prefetch, Q
from django.http import Http404, HttpResponse
from django.shortcuts import render, get_object_or_404
from loguru import logger
from article.models import Article
from base.models import MainMenu
from news.models import NewsSection, News
from utils.format import get_now_strftime_format
# Create your views here.
# 2. 新增:文章详情视图函数
def article_detail(request, pk: int):
"""
根据主键 (pk) 获取文章详情
"""
try:
# 使用 get_object_or_404 简化代码:如果文章不存在,自动返回 404 页面
article = get_object_or_404(Article, pk=pk)
# 如果是渲染 HTML 模板
return render(request, 'front/details/article.html', {'article': article})
except (Article.DoesNotExist, Http404):
return render(request, 'front/error/404.html')
except Exception as e:
logger.error(e)
logger.error(traceback.format_exc())
return render(request, 'front/error/500.html')
def news_detail(request, pk: int):
"""
根据主键 (pk) 获取文章详情
"""
try:
# 使用 get_object_or_404 简化代码:如果文章不存在,自动返回 404 页面
article = get_object_or_404(News, pk=pk)
# 如果是渲染 HTML 模板
return render(request, 'front/details/news.html', {'article': article})
except (News.DoesNotExist, Http404):
return render(request, 'front/error/404.html')
except Exception as e:
logger.error(e)
logger.error(traceback.format_exc())
return render(request, 'front/error/500.html')
def index(request):
# 时间字符串
time_str = get_now_strftime_format()
news_sections = NewsSection.objects.filter(visible=True).order_by('order')
news_data = {
"key": "news",
"data": {
section.title: section.news_set.filter(is_published=True).order_by("-created_at")
for section in news_sections
}
}
articles_qs = Article.objects.filter(is_published=True).order_by('-created_at')
main_sections = MainMenu.objects.filter(parent__isnull=True, visible=True).order_by('order').prefetch_related(
# 预取可见的子板块
Prefetch('children', queryset=MainMenu.objects.filter(visible=True).order_by('order')),
# 预取子板块下的文章,并将结果存入 'latest_articles' 属性
# 注意:这个属性是属于 'children' (即下面的 sub) 的
Prefetch('children__article_set', queryset=articles_qs, to_attr='latest_articles')
)
# 3. 构建数据 (纯内存操作,速度极快)
section_data = [{
"key": main.code,
"data": {main.title: articles_qs.filter(section__in=main.children.all()).order_by('-created_at')[:7]}
} for main in main_sections]
logger.info(section_data)
carousel = {
"key": "index",
"data": [
{
"id": 0,
"image_url": "/media/upload/images/2022/12/15/11146164001.jpg",
"title": "First slide label",
# "description": "Some representative placeholder content for the first slide."
},
{
"id": 1,
"image_url": "/media/upload/images/2022/12/15/11142163743.jpg",
"title": "Second slide label",
# "description": "Some representative placeholder content for the second slide."
},
{
"id": 2,
"image_url": "/media/upload/images/2022/12/15/11150164804.jpg",
"title": "Third slide label",
# "description": "Some representative placeholder content for the third slide."
}
]
}
return render(request, 'front/index.html', {
'time_str': time_str,
'news_data': news_data,
'section_data': section_data,
'carousel': carousel,
})
def about(request):
return render(request, 'front/about.html', {
'leaders': [],
'about': {'content': '这里是单位简介'},
'org_list': [],
})
def news(request):
sections = NewsSection.objects.filter(visible=True).all().order_by('order')
section_data = [
{
"key": sec.code,
"data": {
sec.title: sec.news_set.filter(is_published=True)[:7],
}
}
for sec in sections
]
context = {
'sections': section_data,
}
logger.info(context)
return render(request, 'front/news.html', context)
def section(request, main):
"""信息公开"""
logger.info(f"正在访问 {main}")
main_section = MainMenu.objects.filter(code=main).first()
if not main_section:
raise Http404("不存在的板块")
sections = MainMenu.objects.filter(parent__isnull=False, parent__code=main).order_by('order')
sections_data = [
{
"key": section.code,
"data": {
section.title: section.article_set.filter(is_published=True).order_by('-created_at')[:7],
}
}
for section in sections]
logger.info(sections_data)
context = {
'main_section': main_section,
'sections': sections_data,
}
return render(request, 'front/info.html', context=context)
def main_news_list(request):
logger.info("正在访问新闻中心")
news_list = News.objects.filter(is_published=True).all()
news_sections = NewsSection.objects.filter(visible=True).all()
# 分页参数
news_list = custom_pagination(news_list, request)
context = {
'main_section': {
'title': '新闻中心',
'code': 'news'
},
'articles': news_list,
'sections': news_sections,
}
return render(request, 'front/list.html', context)
def custom_pagination(news_list, request):
page = request.GET.get('page', 1) # 当前页码,默认第1页
per_page = request.GET.get('per_page', 20) # 每页显示条数,默认20
# 创建分页器
paginator = Paginator(news_list, per_page)
try:
# 获取当前页数据
news_list = paginator.page(page)
except PageNotAnInteger:
# 如果页码不是整数,返回第一页
news_list = paginator.page(1)
except EmptyPage:
# 如果页码超出范围,返回最后一页
news_list = paginator.page(paginator.num_pages)
return news_list
def sub_news_list(request, sub: str):
logger.info(f"正在访问 {sub}")
sections = NewsSection.objects.filter(visible=True).order_by('order')
logger.info(f"新闻板块: {sections}")
main_section = {
'title': '新闻中心',
'code': 'news'
}
sub_section = sections.filter(code=sub).first()
logger.info(f"主板块 {main_section} 子板块 {sub_section}")
if not sub_section or not main_section:
raise Http404("不存在的板块")
news_list = sub_section.news_set.filter(is_published=True).order_by('-created_at')[:21]
news_list = custom_pagination(news_list, request)
context = {
'main_section': main_section,
'sub_section': sub_section,
'sections': sections,
'articles': news_list
}
logger.info(context)
return render(request, 'front/list.html', context=context)
def main_article_list(request, main):
"""信息公开"""
logger.info(f"正在访问 {main}")
main_section = MainMenu.objects.filter(code=main).first()
if not main_section:
raise Http404("不存在的板块")
articles_qs = Article.objects.filter(is_published=True, section__in=main_section.active_children).order_by(
'-created_at')
sections = main_section.active_children.order_by('order').prefetch_related(
Prefetch('article_set', queryset=articles_qs, to_attr='latest_articles')
)
articles = custom_pagination(articles_qs, request)
context = {
'main_section': main_section,
'sections': sections,
'articles': articles,
}
return render(request, 'front/list.html', context=context)
def sub_article_list(request, main: str, sub: str):
"""信息公开"""
logger.info(f"正在访问 {main}")
sections = MainMenu.objects.all().order_by('order')
main_section = sections.filter(code=main).first()
sub_section = sections.filter(code=sub, parent__code=main).first()
logger.info(f"主板块 {main_section} 子板块 {sub_section}")
if not sub_section or not main_section:
raise Http404("不存在的板块")
articles = sub_section.article_set.filter(is_published=True).order_by('-created_at')
articles = custom_pagination(articles, request)
context = {
'main_section': main_section,
'sub_section': sub_section,
'sections': sections.filter(parent__code=main),
'articles': articles
}
return render(request, 'front/list.html', context=context)