461 lines
21 KiB
Python
461 lines
21 KiB
Python
import traceback
|
|
from typing import Dict, List
|
|
from unicodedata import category
|
|
|
|
from django.db.models import Prefetch
|
|
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 = []
|
|
for main in main_sections:
|
|
# 收集该主板块下所有子板块的文章
|
|
all_articles = []
|
|
for sub in main.children.all():
|
|
# 使用预取好的 children
|
|
# 使用预取好的 latest_articles,并取前7条
|
|
all_articles.extend(sub.latest_articles[:7])
|
|
all_articles.sort(key=lambda x: x.created_at, reverse=True)
|
|
# 截取总列表的前7条(如果需要限制总数)
|
|
section_data.append({
|
|
"key": main.code, # 建议使用 code 作为 key,比对象本身更安全
|
|
"data": {
|
|
main.title: all_articles[:7]
|
|
}
|
|
})
|
|
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": section.code,
|
|
"data": {
|
|
section.title: section.news_set.filter(is_published=True)[:7],
|
|
}
|
|
}
|
|
for section in sections
|
|
]
|
|
|
|
context = {
|
|
'sections': section_data,
|
|
}
|
|
logger.info(context)
|
|
return render(request, 'front/news.html', context)
|
|
|
|
|
|
def info(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_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).order_by('-created_at')
|
|
|
|
sections = main_section.active_children.order_by('order').prefetch_related(
|
|
Prefetch('article_set', queryset=articles_qs, to_attr='latest_articles')
|
|
)
|
|
section_data = {
|
|
"key": main_section,
|
|
"data": {
|
|
main_section.title: [
|
|
article
|
|
for section in sections
|
|
for article in section.latest_articles[:7]
|
|
],
|
|
}
|
|
}
|
|
|
|
logger.info(section_data)
|
|
context = {
|
|
'main_section': main_section,
|
|
'sections': sections,
|
|
'articles': [
|
|
article
|
|
for section in sections
|
|
for article in section.latest_articles[:7]
|
|
]
|
|
}
|
|
return render(request, 'front/list.html', context=context)
|
|
|
|
|
|
def sub_news_list(request, sub: str):
|
|
logger.info(f"正在访问 {sub}")
|
|
sections = NewsSection.objects.all().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("不存在的板块")
|
|
context = {
|
|
'main_section': main_section,
|
|
'sub_section': sub_section,
|
|
'sections': sections,
|
|
'articles': sub_section.news_set.filter(is_published=True).order_by('-created_at')[:21]
|
|
}
|
|
return render(request, 'front/list.html', context=context)
|
|
|
|
|
|
def main_news_list(request):
|
|
logger.info("正在访问新闻中心")
|
|
news_list = News.objects.all()
|
|
news_sections = NewsSection.objects.all()
|
|
return render(request, 'front/list.html', {
|
|
'main_section': {
|
|
'title': '新闻中心',
|
|
'code': 'news'
|
|
},
|
|
'articles': news_list,
|
|
'sections': news_sections,
|
|
})
|
|
|
|
|
|
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("不存在的板块")
|
|
context = {
|
|
'main_section': main_section,
|
|
'sub_section': sub_section,
|
|
'sections': sections.filter(parent__code=main),
|
|
'articles': sub_section.article_set.filter(is_published=True).order_by('-created_at')[:21]
|
|
}
|
|
return render(request, 'front/list.html', context=context)
|
|
|
|
|
|
def service(request):
|
|
"""办事服务"""
|
|
q = request.GET.get('q') or "办事指南"
|
|
sections = [
|
|
"办事指南",
|
|
"政务服务",
|
|
"资料下载",
|
|
"办事统计",
|
|
]
|
|
data = {
|
|
"办事指南": [
|
|
{'title': '中共长白山保护开发区工委办公室关于印发杨文慧同志在 2026...', 'date': '2026-03-05'},
|
|
{'title': '长白山管委会办公室关于印发《长白山保护开发区落实<吉林省...', 'date': '2026-02-28'},
|
|
{'title': '长白山保护开发区管理委员会 2025 年度行政执法工作报告', 'date': '2026-01-30'},
|
|
{'title': '长白山管委会办公室关于印发《美丽长白山建设行动方案(202...', 'date': '2025-12-31'},
|
|
{'title': '长白山管委会办公室关于印发《长白山保护开发区碳达峰实施...', 'date': '2025-12-31'},
|
|
{'title': '《长白山保护开发区防雷减灾管理办法》政策解读', 'date': '2025-12-12'},
|
|
],
|
|
"政务服务": [
|
|
{'title': '《长白山保护开发区防雷减灾管理办法》政策解读', 'date': '2025-12-12'},
|
|
{'title': '《长白山保护开发区旅游漂流活动管理规范》政策解读', 'date': '2025-07-23'},
|
|
{'title': '《长白山 40 米射电望远镜电磁波宁静区保护办法》政策解读', 'date': '2025-07-23'},
|
|
{'title': '《长白山保护开发区古树名木管理办法(试行)》政策解读', 'date': '2025-06-18'},
|
|
{'title': '《长白山保护开发区公共租赁住房管理办法》政策解读', 'date': '2025-04-08'},
|
|
{'title': '《长白山保护开发区旅游民宿管理与服务规范(试行)》政策解读', 'date': '2024-12-31'},
|
|
],
|
|
"资料下载": [
|
|
{'title': '关于第二轮中央生态环境保护督察第四十一项整改任务销号...', 'date': '2026-03-11'},
|
|
{'title': '关于第二轮中央生态环境保护督察第三十八项整改任务销号...', 'date': '2026-03-11'},
|
|
{'title': '公告送达通知', 'date': '2026-03-10'},
|
|
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
|
|
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
|
|
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
|
|
]
|
|
}
|
|
context = {
|
|
"sections": sections,
|
|
"data_list": data.get(q),
|
|
"q": q,
|
|
}
|
|
return render(request, 'front/service.html', context)
|
|
|
|
|
|
def party(request):
|
|
"""党建引领"""
|
|
sections: List[Dict] = [
|
|
{
|
|
"key": "party_work",
|
|
"data": {
|
|
"党建工作": [
|
|
{'title': '关于第二轮中央生态环境保护督察第四十一项整改任务销号...', 'date': '2026-03-11'},
|
|
{'title': '关于第二轮中央生态环境保护督察第三十八项整改任务销号...', 'date': '2026-03-11'},
|
|
{'title': '公告送达通知', 'date': '2026-03-10'},
|
|
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
|
|
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
|
|
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"key": "integrity",
|
|
"data": {
|
|
"党风廉政": [
|
|
# ⚠️ 请替换为真实的法律法规数据
|
|
{'title': '关于第二轮中央生态环境保护督察第四十一项整改任务销号...', 'date': '2026-03-11'},
|
|
{'title': '关于第二轮中央生态环境保护督察第三十八项整改任务销号...', 'date': '2026-03-11'},
|
|
{'title': '公告送达通知', 'date': '2026-03-10'},
|
|
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
|
|
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
|
|
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"key": "advance",
|
|
"data": {
|
|
"先进典型": [
|
|
{'title': '中共长白山保护开发区工委办公室关于印发杨文慧同志在 2026...', 'date': '2026-03-05'},
|
|
{'title': '长白山管委会办公室关于印发《长白山保护开发区落实<吉林省...', 'date': '2026-02-28'},
|
|
{'title': '长白山保护开发区管理委员会 2025 年度行政执法工作报告', 'date': '2026-01-30'},
|
|
{'title': '长白山管委会办公室关于印发《美丽长白山建设行动方案(202...', 'date': '2025-12-31'},
|
|
{'title': '长白山管委会办公室关于印发《长白山保护开发区碳达峰实施...', 'date': '2025-12-31'},
|
|
{'title': '《长白山保护开发区防雷减灾管理办法》政策解读', 'date': '2025-12-12'},
|
|
]
|
|
}
|
|
},
|
|
|
|
]
|
|
carousel: Dict = {
|
|
"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."
|
|
}
|
|
]
|
|
}
|
|
sections.insert(1, carousel)
|
|
context = {
|
|
'sections': sections,
|
|
}
|
|
|
|
return render(request, 'front/party.html', context)
|
|
|
|
|
|
def interaction(request):
|
|
"""互动交流"""
|
|
q = request.GET.get('q') or "专家访谈"
|
|
sections = [
|
|
"专家访谈",
|
|
"调查征集",
|
|
"在线咨询",
|
|
]
|
|
data = {
|
|
"专家访谈": [
|
|
{'title': '中共长白山保护开发区工委办公室关于印发杨文慧同志在 2026...', 'date': '2026-03-05'},
|
|
{'title': '长白山管委会办公室关于印发《长白山保护开发区落实<吉林省...', 'date': '2026-02-28'},
|
|
{'title': '长白山保护开发区管理委员会 2025 年度行政执法工作报告', 'date': '2026-01-30'},
|
|
{'title': '长白山管委会办公室关于印发《美丽长白山建设行动方案(202...', 'date': '2025-12-31'},
|
|
{'title': '长白山管委会办公室关于印发《长白山保护开发区碳达峰实施...', 'date': '2025-12-31'},
|
|
{'title': '《长白山保护开发区防雷减灾管理办法》政策解读', 'date': '2025-12-12'},
|
|
],
|
|
"调查征集": [
|
|
{'title': '《长白山保护开发区防雷减灾管理办法》政策解读', 'date': '2025-12-12'},
|
|
{'title': '《长白山保护开发区旅游漂流活动管理规范》政策解读', 'date': '2025-07-23'},
|
|
{'title': '《长白山 40 米射电望远镜电磁波宁静区保护办法》政策解读', 'date': '2025-07-23'},
|
|
{'title': '《长白山保护开发区古树名木管理办法(试行)》政策解读', 'date': '2025-06-18'},
|
|
{'title': '《长白山保护开发区公共租赁住房管理办法》政策解读', 'date': '2025-04-08'},
|
|
{'title': '《长白山保护开发区旅游民宿管理与服务规范(试行)》政策解读', 'date': '2024-12-31'},
|
|
],
|
|
"在线咨询": [
|
|
{'title': '关于第二轮中央生态环境保护督察第四十一项整改任务销号...', 'date': '2026-03-11'},
|
|
{'title': '关于第二轮中央生态环境保护督察第三十八项整改任务销号...', 'date': '2026-03-11'},
|
|
{'title': '公告送达通知', 'date': '2026-03-10'},
|
|
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
|
|
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
|
|
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
|
|
]
|
|
}
|
|
context = {
|
|
"sections": sections,
|
|
"data_list": data.get(q),
|
|
"q": q,
|
|
}
|
|
return render(request, 'front/interaction.html', context)
|
|
|
|
|
|
def science(request):
|
|
"""消防科普"""
|
|
q = request.GET.get('q') or "数字消防"
|
|
sections = [
|
|
"数字消防",
|
|
"火灾预防",
|
|
"自救逃生",
|
|
]
|
|
data = {
|
|
"数字消防": [
|
|
{'title': '中共长白山保护开发区工委办公室关于印发杨文慧同志在 2026...', 'date': '2026-03-05'},
|
|
{'title': '长白山管委会办公室关于印发《长白山保护开发区落实<吉林省...', 'date': '2026-02-28'},
|
|
{'title': '长白山保护开发区管理委员会 2025 年度行政执法工作报告', 'date': '2026-01-30'},
|
|
{'title': '长白山管委会办公室关于印发《美丽长白山建设行动方案(202...', 'date': '2025-12-31'},
|
|
{'title': '长白山管委会办公室关于印发《长白山保护开发区碳达峰实施...', 'date': '2025-12-31'},
|
|
{'title': '《长白山保护开发区防雷减灾管理办法》政策解读', 'date': '2025-12-12'},
|
|
],
|
|
"火灾预防": [
|
|
{'title': '《长白山保护开发区防雷减灾管理办法》政策解读', 'date': '2025-12-12'},
|
|
{'title': '《长白山保护开发区旅游漂流活动管理规范》政策解读', 'date': '2025-07-23'},
|
|
{'title': '《长白山 40 米射电望远镜电磁波宁静区保护办法》政策解读', 'date': '2025-07-23'},
|
|
{'title': '《长白山保护开发区古树名木管理办法(试行)》政策解读', 'date': '2025-06-18'},
|
|
{'title': '《长白山保护开发区公共租赁住房管理办法》政策解读', 'date': '2025-04-08'},
|
|
{'title': '《长白山保护开发区旅游民宿管理与服务规范(试行)》政策解读', 'date': '2024-12-31'},
|
|
],
|
|
"自救逃生": [
|
|
{'title': '关于第二轮中央生态环境保护督察第四十一项整改任务销号...', 'date': '2026-03-11'},
|
|
{'title': '关于第二轮中央生态环境保护督察第三十八项整改任务销号...', 'date': '2026-03-11'},
|
|
{'title': '公告送达通知', 'date': '2026-03-10'},
|
|
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
|
|
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
|
|
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
|
|
]
|
|
}
|
|
context = {
|
|
"sections": sections,
|
|
"data_list": data.get(q),
|
|
"q": q,
|
|
}
|
|
return render(request, 'front/science.html', context)
|