diff --git a/article/admin.py b/article/admin.py index fd36a38..d0c3d55 100644 --- a/article/admin.py +++ b/article/admin.py @@ -83,18 +83,18 @@ class ArticleForm(forms.ModelForm): super().__init__(*args, **kwargs) # 核心代码:过滤 section 字段,只保留有父级的分类(即二级分类) # 这里的 queryset 会直接作用于 Admin 的下拉选择框 - self.fields['section'].queryset = MainMenu.objects.filter(parent__isnull=False, enabled=True) + self.fields['section'].queryset = MainMenu.objects.filter(parent__isnull=False, visible=True) # 可选:优化显示格式,让用户知道是哪个主板块下的子板块 # 例如显示:"[新闻中心] 国内新闻" - self.fields['section'].label_from_instance = lambda obj: f"[{obj.parent.name}] {obj.name}" + self.fields['section'].label_from_instance = lambda obj: f"[{obj.parent.title}] {obj.title}" # —————— 文章 —————— @admin.register(Article) class ArticleAdmin(ImportExportModelAdmin): form = ArticleForm # <--- 关联自定义表单 - list_display = ('title', 'section', 'author', 'is_published', 'created_at') + list_display = ('title', 'section', 'author', 'is_published', 'created_at', 'attachment_count') list_filter = ('section', 'is_published', 'created_at') search_fields = ('title', 'content') date_hierarchy = 'created_at' @@ -108,6 +108,17 @@ class ArticleAdmin(ImportExportModelAdmin): ('发布设置', {'fields': ('is_published',)}), ) + # 2. 定义显示附件数量的方法 + def attachment_count(self, obj): + # 使用 count() 方法统计数量 + count = obj.attachments.count() + if count == 0: + return "-" # 没有附件显示横杠 + return f"📎 {count}" # 有附件显示图标和数量 + + # 3. 设置该列在后台的标题 + attachment_count.short_description = "附件" + # —————— 通知(带签收) —————— @admin.register(Notice) diff --git a/article/seeder.py b/article/seeder.py index 11e2e91..ab28d15 100644 --- a/article/seeder.py +++ b/article/seeder.py @@ -39,8 +39,48 @@ def seed_articles(count=20): section = random.choice(subsections) author = random.choice(users) if users else None - paragraphs = fake.paragraphs(nb=random.randint(3, 8)) - content_html = "\n".join([f"

{p}

" for p in paragraphs]) + # --- 2. 构建丰富的 HTML 内容 --- + html_parts = [] + + # A. 开头:一段引言或摘要 + if random.random() > 0.5: + html_parts.append(f"

【摘要】 {fake.sentence(nb_words=10)}

") + + # B. 正文第一段 + html_parts.append(f"

{fake.paragraph(nb_sentences=4)}

") + + # C. 随机插入图片占位符 (模拟上传的封面或插图) + # 使用 placehold.co 生成带文字的灰色占位图 + img_width = random.choice([600, 800]) + img_height = random.choice([300, 400]) + img_text = fake.words(nb=3, unique=True) + html_parts.append( + f'
') + + # D. 正文中间段落 + html_parts.append(f"

{fake.paragraph(nb_sentences=5)}

") + + # E. 随机插入引用块 (增加排版层次感) + if random.random() > 0.6: + quote = fake.sentence(nb_words=8) + html_parts.append( + f'
"{quote}"
') + + # F. 随机插入无序列表 (模拟要点陈述) + if random.random() > 0.7: + list_items = "".join([f"
  • {fake.sentence()}
  • " for _ in range(3)]) + html_parts.append(f"") + + # G. 加粗和斜体混合段落 + p1 = fake.paragraph(nb_sentences=2) + p2 = fake.paragraph(nb_sentences=2) + html_parts.append(f"

    {p1} {fake.words(nb=4, unique=True)} {p2}

    ") + + # H. 结尾 + html_parts.append(f"

    {fake.paragraph(nb_sentences=3)}

    ") + + # 拼接最终 HTML + content_html = "\n".join(html_parts) article = Article.objects.create( title=fake.sentence(nb_words=random.randint(5, 10))[:-1], @@ -81,4 +121,4 @@ def seed_articles(count=20): if __name__ == "__main__": - seed_articles(30) + seed_articles(120) diff --git a/base/admin.py b/base/admin.py index 2241a97..30023fd 100644 --- a/base/admin.py +++ b/base/admin.py @@ -23,7 +23,7 @@ class MainMenuAdmin(ImportExportModelAdmin): display_name.admin_order_field = 'name' def is_enabled(self, obj): - return obj.enabled + return obj.visible is_enabled.boolean = True is_enabled.short_description = '启用' diff --git a/base/templatetags/footer_tags.py b/base/templatetags/footer_tags.py index 35de31c..31eea3c 100644 --- a/base/templatetags/footer_tags.py +++ b/base/templatetags/footer_tags.py @@ -23,8 +23,9 @@ def show_footer(): } -@register.inclusion_tag('components/main_menu.html') -def show_main_menu(): +@register.inclusion_tag('components/main_menu.html', takes_context=True) +def show_main_menu(context): + request = context['request'] # 1. 获取当前生效的那一条页脚数据 # 根据你之前的模型,is_active=True 的只有一条 menus = MainMenu.objects.filter(visible=True, parent__isnull=True).order_by('order') @@ -33,4 +34,5 @@ def show_main_menu(): # 3. 将数据传递给模板 return { 'menus': menus, + 'request': request, } diff --git a/front/urls.py b/front/urls.py index 59e4ea9..03c4bcb 100644 --- a/front/urls.py +++ b/front/urls.py @@ -12,9 +12,10 @@ urlpatterns = [ path('about/', views.about, name='about'), path('news/', views.news, name='news'), path('info/', views.info, name='info'), - path('service/', views.service, name='service'), + path('news/.html', views.sub_news_list, name='news_list'), path('party/', views.party, name='party'), path('interaction/', views.interaction, name='interaction'), path('science/', views.science, name='science'), path('article/.html/', views.article_detail, name='article_detail'), + path('news/.html/', views.news_detail, name='news_detail'), ] diff --git a/front/views.py b/front/views.py index 2039926..94c800f 100644 --- a/front/views.py +++ b/front/views.py @@ -9,7 +9,7 @@ from loguru import logger from article.models import Article from base.models import MainMenu -from news.models import NewsSection +from news.models import NewsSection, News from utils.format import get_now_strftime_format @@ -32,91 +32,35 @@ def article_detail(request, pk: int): 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": "important", + "key": "news", "data": { - '消防要闻': [ - {'title': '习近平会见全国应急管理系统先进模范和消防忠诚卫士表彰...', 'date': '2021-11-06'}, - {'title': '北京市消防救援局挂牌', 'date': '2024-06-19'}, - {'title': '市消防救援局即日起开展专项行动,推出一揽子“便民利企”措施', 'date': '2025-07-01'}, - {'title': '北京开展石油化工生产装置灭火救援实战演练', 'date': '2025-09-30'}, - {'title': '北京市全面启动 2025 年度消防宣传月活动', 'date': '2025-11-11'}, - {'title': '逛庙会学消防!厂甸大观园庙会打造消防“打卡点”', 'date': '2026-02-25'}, - {'title': '“火焰蓝”守护年味!消防员坚守景区庙会护平安', 'date': '2026-02-21'}, - ], - '基层动态': [ - {'title': '某支队开展冬季练兵比武活动', 'date': '2023-12-01'}, - {'title': '社区微型消防站进行应急演练', 'date': '2023-12-05'}, - {'title': '朝阳区举办消防安全知识讲座', 'date': '2024-01-15'}, - ], - '国务院新闻': [ - {'title': '国务院安委会部署全国安全生产大检查', 'date': '2023-11-20'}, - ] + section.title: section.news_set.filter(is_published=True).order_by("-created_at") + for section in news_sections } } - # section_data = [ - # { - # "key": "info", - # "data": { - # '信息公开': [ - # {'title': '习近平会见全国应急管理系统先进模范和消防忠诚卫士表彰...', 'date': '2021-11-06'}, - # {'title': '北京市消防救援局挂牌', 'date': '2024-06-19'}, - # {'title': '市消防救援局即日起开展专项行动,推出一揽子“便民利企”措施', 'date': '2025-07-01'}, - # {'title': '北京开展石油化工生产装置灭火救援实战演练', 'date': '2025-09-30'}, - # {'title': '北京市全面启动 2025 年度消防宣传月活动', 'date': '2025-11-11'}, - # {'title': '逛庙会学消防!厂甸大观园庙会打造消防“打卡点”', 'date': '2026-02-25'}, - # {'title': '“火焰蓝”守护年味!消防员坚守景区庙会护平安', 'date': '2026-02-21'}, - # ], - # }, - # }, - # { - # "key": "party", - # "data": { - # '党建引领': [ - # {'title': '习近平会见全国应急管理系统先进模范和消防忠诚卫士表彰...', 'date': '2021-11-06'}, - # {'title': '北京市消防救援局挂牌', 'date': '2024-06-19'}, - # {'title': '市消防救援局即日起开展专项行动,推出一揽子“便民利企”措施', 'date': '2025-07-01'}, - # {'title': '北京开展石油化工生产装置灭火救援实战演练', 'date': '2025-09-30'}, - # {'title': '北京市全面启动 2025 年度消防宣传月活动', 'date': '2025-11-11'}, - # {'title': '逛庙会学消防!厂甸大观园庙会打造消防“打卡点”', 'date': '2026-02-25'}, - # {'title': '“火焰蓝”守护年味!消防员坚守景区庙会护平安', 'date': '2026-02-21'}, - # ], - # }, - # }, - # { - # "key": "interaction", - # "data": { - # '互动交流': [ - # {'title': '习近平会见全国应急管理系统先进模范和消防忠诚卫士表彰...', 'date': '2021-11-06'}, - # {'title': '北京市消防救援局挂牌', 'date': '2024-06-19'}, - # {'title': '市消防救援局即日起开展专项行动,推出一揽子“便民利企”措施', 'date': '2025-07-01'}, - # {'title': '北京开展石油化工生产装置灭火救援实战演练', 'date': '2025-09-30'}, - # {'title': '北京市全面启动 2025 年度消防宣传月活动', 'date': '2025-11-11'}, - # {'title': '逛庙会学消防!厂甸大观园庙会打造消防“打卡点”', 'date': '2026-02-25'}, - # {'title': '“火焰蓝”守护年味!消防员坚守景区庙会护平安', 'date': '2026-02-21'}, - # ], - # }, - # }, - # { - # "key": "science", - # "data": { - # '消防科普': [ - # {'title': '习近平会见全国应急管理系统先进模范和消防忠诚卫士表彰...', 'date': '2021-11-06'}, - # {'title': '北京市消防救援局挂牌', 'date': '2024-06-19'}, - # {'title': '市消防救援局即日起开展专项行动,推出一揽子“便民利企”措施', 'date': '2025-07-01'}, - # {'title': '北京开展石油化工生产装置灭火救援实战演练', 'date': '2025-09-30'}, - # {'title': '北京市全面启动 2025 年度消防宣传月活动', 'date': '2025-11-11'}, - # {'title': '逛庙会学消防!厂甸大观园庙会打造消防“打卡点”', 'date': '2026-02-25'}, - # {'title': '“火焰蓝”守护年味!消防员坚守景区庙会护平安', 'date': '2026-02-21'}, - # ], - # }, - # } - # ] + 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( # 预取可见的子板块 @@ -184,12 +128,12 @@ def about(request): def news(request): - sections = NewsSection.objects.filter(enabled=True).all().order_by('order') + sections = NewsSection.objects.filter(visible=True).all().order_by('order') section_data = [ { "key": section.code, "data": { - section.name: section.news_set.filter(is_published=True)[:7], + section.title: section.news_set.filter(is_published=True)[:7], } } for section in sections @@ -260,6 +204,41 @@ def main_article_list(request, main): 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}") diff --git a/news/admin.py b/news/admin.py index c743c97..46f8313 100644 --- a/news/admin.py +++ b/news/admin.py @@ -11,11 +11,11 @@ from .models import NewsSection, News # --- 1. 板块管理配置 --- @admin.register(NewsSection) class NewsSectionAdmin(ImportExportModelAdmin): - list_display = ('name', 'code', 'order', 'enabled') # 列表显示的字段 - list_editable = ('order', 'enabled') # 允许直接在列表页修改排序和状态 - search_fields = ('name', 'code') # 搜索框 - prepopulated_fields = {'code': ('name',)} # 输入名称时自动生成 Slug - ordering = ('order', 'name') # 默认排序 + list_display = ('title', 'code', 'order', 'visible') # 列表显示的字段 + list_editable = ('order', 'visible') # 允许直接在列表页修改排序和状态 + search_fields = ('title', 'code') # 搜索框 + prepopulated_fields = {'code': ('title',)} # 输入名称时自动生成 Slug + ordering = ('order', 'title') # 默认排序 # --- 2. 文章管理配置 --- diff --git a/news/migrations/0003_alter_newssection_options_and_more.py b/news/migrations/0003_alter_newssection_options_and_more.py new file mode 100644 index 0000000..34619f5 --- /dev/null +++ b/news/migrations/0003_alter_newssection_options_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 6.0.3 on 2026-04-01 09:21 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('news', '0002_initial'), + ] + + operations = [ + migrations.AlterModelOptions( + name='newssection', + options={'ordering': ('order', 'title'), 'verbose_name': '新闻模块', 'verbose_name_plural': '新闻模块'}, + ), + migrations.RenameField( + model_name='newssection', + old_name='name', + new_name='title', + ), + migrations.RenameField( + model_name='newssection', + old_name='enabled', + new_name='visible', + ), + ] diff --git a/news/models.py b/news/models.py index ab23b83..4d5c28e 100644 --- a/news/models.py +++ b/news/models.py @@ -7,18 +7,18 @@ from users.models import User # Create your models here. class NewsSection(BaseEntity): - name = models.CharField('模块名称', max_length=100, unique=True) + title = models.CharField('模块名称', max_length=100, unique=True) code = models.SlugField('唯一标识', max_length=50, unique=True, help_text='用于模板或URL识别,建议英文') order = models.PositiveSmallIntegerField('排序权重', default=0) - enabled = models.BooleanField('启用状态', default=True) + visible = models.BooleanField('启用状态', default=True) class Meta: verbose_name = '新闻模块' verbose_name_plural = '新闻模块' - ordering = ('order', 'name') + ordering = ('order', 'title') def __str__(self): - return self.name + return self.title class News(BaseEntity): diff --git a/news/seeder.py b/news/seeder.py index 1441257..d4a323a 100644 --- a/news/seeder.py +++ b/news/seeder.py @@ -19,49 +19,81 @@ fake = Faker('zh_CN') def seed_news(count=20): - print(f"🚀 开始生成 {count} 条新闻数据...") + print(f"🚀 开始生成 {count} 条富文本新闻数据...") # --- 1. 获取关联数据 --- - # 获取所有板块 sections = list(NewsSection.objects.all()) - # 获取所有用户 users = list(User.objects.all()) - # 检查基础数据是否存在 if not sections: - print("❌ 错误:数据库中没有找到任何板块 (NewsSection)!请先添加板块。") + print("❌ 错误:数据库中没有找到任何板块 (NewsSection)!") return - if not users: - print("⚠️ 警告:数据库中没有用户 (User),作者字段将设为空。") - # --- 2. 生成数据 --- created_count = 0 + for i in range(count): - # 随机选择一个板块 section = random.choice(sections) - # 随机选择一个作者 (如果有用户) author = random.choice(users) if users else None - # 生成富文本内容 (模拟 CKEditor 输出的 HTML) - # paragrahs 生成多段文本,join 拼接 - paragraphs = fake.paragraphs(nb=random.randint(3, 6)) - content_html = "\n".join([f"

    {p}

    " for p in paragraphs]) + # --- 2. 构建丰富的 HTML 内容 --- + html_parts = [] - # 创建新闻对象 + # A. 开头:一段引言或摘要 + if random.random() > 0.5: + html_parts.append(f"

    【摘要】 {fake.sentence(nb_words=10)}

    ") + + # B. 正文第一段 + html_parts.append(f"

    {fake.paragraph(nb_sentences=4)}

    ") + + # C. 随机插入图片占位符 (模拟上传的封面或插图) + # 使用 placehold.co 生成带文字的灰色占位图 + img_width = random.choice([600, 800]) + img_height = random.choice([300, 400]) + img_text = fake.words(nb=3, unique=True) + html_parts.append( + f'
    ') + + # D. 正文中间段落 + html_parts.append(f"

    {fake.paragraph(nb_sentences=5)}

    ") + + # E. 随机插入引用块 (增加排版层次感) + if random.random() > 0.6: + quote = fake.sentence(nb_words=8) + html_parts.append( + f'
    "{quote}"
    ') + + # F. 随机插入无序列表 (模拟要点陈述) + if random.random() > 0.7: + list_items = "".join([f"
  • {fake.sentence()}
  • " for _ in range(3)]) + html_parts.append(f"
      {list_items}
    ") + + # G. 加粗和斜体混合段落 + p1 = fake.paragraph(nb_sentences=2) + p2 = fake.paragraph(nb_sentences=2) + html_parts.append(f"

    {p1} {fake.words(nb=4, unique=True)} {p2}

    ") + + # H. 结尾 + html_parts.append(f"

    {fake.paragraph(nb_sentences=3)}

    ") + + # 拼接最终 HTML + content_html = "\n".join(html_parts) + + # --- 3. 创建对象 --- news = News.objects.create( - title=fake.sentence(nb_words=random.randint(4, 8))[:-1], # 生成标题并去掉末尾句号 + title=fake.sentence(nb_words=random.randint(4, 8))[:-1], section=section, author=author, content=content_html, - is_published=True, # 默认已发布 - # 封面图留空,因为自动生成图片文件比较复杂,建议手动上传测试图 + is_published=True, + # 可以在这里加上摘要字段,如果有的话 + # summary=fake.paragraph(nb_sentences=1) ) created_count += 1 - print(f" - [{section.name}] {news.title}") + print(f" - [{section.title}] {news.title}") - print(f"✅ 成功生成 {created_count} 条新闻数据!") + print(f"✅ 成功生成 {created_count} 条富文本新闻数据!") if __name__ == "__main__": - seed_news(30) + seed_news(120) diff --git a/templates/components/_news_card.html b/templates/components/_news_card.html index 4f9ced9..fb7ff85 100644 --- a/templates/components/_news_card.html +++ b/templates/components/_news_card.html @@ -47,7 +47,7 @@ {% if items %} {% for item in items %}
  • -
    diff --git a/templates/components/main_menu.html b/templates/components/main_menu.html index 9f7b415..fd9b083 100644 --- a/templates/components/main_menu.html +++ b/templates/components/main_menu.html @@ -1,9 +1,10 @@ {% load static %} {% for menu in menus %} - -
  • + + + {% endfor %} diff --git a/templates/front/details/article.html b/templates/front/details/article.html index f29041a..3e014b8 100644 --- a/templates/front/details/article.html +++ b/templates/front/details/article.html @@ -24,7 +24,8 @@

    {{ article.title }}

    {{ article.created_at|date:"Y-m-d H:i" }} - {{ article.author.username|default:"管理员" }} + {{ article.author.username|default:"管理员" }} 阅读数:{{ article.views|default:0 }}
    @@ -32,7 +33,8 @@ {% if article.cover %}
    - {{ article.title }} + {{ article.title }}
    {% endif %} @@ -40,32 +42,33 @@
    {{ article.content|safe }}
    - - - {% if article.attachments_list %} -
    -
    - 相关附件 -
    - +
    + {% endif %} + {% endwith %} -
    +
    返回上一页 diff --git a/templates/front/details/news.html b/templates/front/details/news.html index e149a39..692e432 100644 --- a/templates/front/details/news.html +++ b/templates/front/details/news.html @@ -1,10 +1,59 @@ - - - - - Title - - +{% extends 'base.html' %} - - +{% block title %}{{ article.section.title }} - 长白山消防救援支队{% endblock %} + +{% block content %} +
    + + + + +
    +
    + + +
    +

    {{ article.title }}

    +
    + {{ article.created_at|date:"Y-m-d H:i" }} + {{ article.author.username|default:"管理员" }} + 阅读数:{{ article.views|default:0 }} +
    +
    + + + {% if article.cover %} +
    + {{ article.title }} +
    + {% endif %} + + +
    + {{ article.content|safe }} +
    + + + + +
    +
    +
    +{% endblock %} diff --git a/templates/front/index.html b/templates/front/index.html index 7b55ded..8888844 100644 --- a/templates/front/index.html +++ b/templates/front/index.html @@ -42,7 +42,8 @@ {% include 'components/_carousel.html' with carousel_id=carousel.key slides=carousel.data height="300px" %}
    - {% include 'components/_news_card.html' with data=news_data.data unique_id=news_data.key %} + {% url "front:news" as more_url %} + {% include 'components/_news_card.html' with data=news_data.data unique_id=news_data.key more_url=more_url route="front:news_detail" %}
    diff --git a/templates/front/info.html b/templates/front/info.html index 735276d..b8eeb50 100644 --- a/templates/front/info.html +++ b/templates/front/info.html @@ -10,7 +10,8 @@
    {% for section in sections %} -
    +
    {% url "front:sub_list" main=main_section.code sub=section.key as card_more_url %} {% include 'components/_news_card.html' with data=section.data unique_id=section.key more_url=card_more_url %} diff --git a/templates/front/interaction.html b/templates/front/interaction.html deleted file mode 100644 index 12c52a5..0000000 --- a/templates/front/interaction.html +++ /dev/null @@ -1,168 +0,0 @@ -{% extends 'base.html' %} -{% block title %}互动交流 - 长白山消防救援支队{% endblock %} -{% block content %} -
    - - -
    -
    -
      -
    • -
      互动交流
      -
    • - {% for sec in sections %} -
    • - {{ sec }} -
    • - {% endfor %} -
    - -
    -
    - -
    - - -
    -
    - - {{ q }} -
    -
    -
    - - {# #} - {#
    #} - {#
    #} - {#
    #} - {#
    #} -
      - {# items 就是当前 key 对应的列表数据,直接使用 #} - {% if data_list %} - {% for item in data_list %} -
    • -
      - - {{ item.title|truncatechars:30 }} -
      - {{ item.date }} -
    • - {% endfor %} - {% else %} -
    • 暂无数据
    • - {% endif %} -
    -
    - -
    - -
    -
    -
    -
    - -{% endblock %} \ No newline at end of file diff --git a/templates/front/list.html b/templates/front/list.html index f462927..9f1737a 100644 --- a/templates/front/list.html +++ b/templates/front/list.html @@ -4,26 +4,58 @@
    diff --git a/templates/front/news.html b/templates/front/news.html index b549502..b882768 100644 --- a/templates/front/news.html +++ b/templates/front/news.html @@ -7,14 +7,15 @@
    {% for section in sections %}
    - {% include 'components/_news_card.html' with data=section.data unique_id=section.key %} + {% url "front:news_list" sub=section.key as more_url %} + {% include 'components/_news_card.html' with data=section.data unique_id=section.key more_url=more_url route="front:news_detail" %}
    {% endfor %}
    diff --git a/templates/front/party.html b/templates/front/party.html deleted file mode 100644 index d605647..0000000 --- a/templates/front/party.html +++ /dev/null @@ -1,23 +0,0 @@ -{% extends 'base.html' %} -{% block title %}党建引领 - 长白山消防救援支队{% endblock %} -{% block content %} -
    - -
    - {% for section in sections %} -
    - {% if forloop.counter == 2 %} - {% include 'components/_carousel.html' with carousel_id=section.key slides=section.data height="300px" %} - {% else %} - {% include 'components/_news_card.html' with data=section.data unique_id=section.key %} - {% endif %} -
    - {% endfor %} -
    -
    -{% endblock %} \ No newline at end of file diff --git a/templates/front/science.html b/templates/front/science.html deleted file mode 100644 index c41c989..0000000 --- a/templates/front/science.html +++ /dev/null @@ -1,168 +0,0 @@ -{% extends 'base.html' %} -{% block title %}消防科普 - 长白山消防救援支队{% endblock %} -{% block content %} -
    - - -
    -
    -
      -
    • -
      消防科普
      -
    • - {% for sec in sections %} -
    • - {{ sec }} -
    • - {% endfor %} -
    - -
    -
    - -
    - - -
    -
    - - {{ q }} -
    -
    -
    - - {# #} - {#
    #} - {#
    #} - {#
    #} - {#
    #} -
      - {# items 就是当前 key 对应的列表数据,直接使用 #} - {% if data_list %} - {% for item in data_list %} -
    • -
      - - {{ item.title|truncatechars:30 }} -
      - {{ item.date }} -
    • - {% endfor %} - {% else %} -
    • 暂无数据
    • - {% endif %} -
    -
    - -
    - -
    -
    -
    -
    - -{% endblock %} \ No newline at end of file diff --git a/templates/front/service.html b/templates/front/service.html deleted file mode 100644 index 1583567..0000000 --- a/templates/front/service.html +++ /dev/null @@ -1,169 +0,0 @@ -{% extends 'base.html' %} -{% block title %}办事服务 - 长白山消防救援支队{% endblock %} -{% block content %} -
    - - - -
    -
    -
      -
    • -
      办事服务
      -
    • - {% for sec in sections %} -
    • - {{ sec }} -
    • - {% endfor %} -
    - -
    -
    - -
    - - -
    -
    - - {{ q }} -
    -
    -
    - - {# #} - {#
    #} - {#
    #} - {#
    #} - {#
    #} -
      - {# items 就是当前 key 对应的列表数据,直接使用 #} - {% if data_list %} - {% for item in data_list %} -
    • -
      - - {{ item.title|truncatechars:30 }} -
      - {{ item.date }} -
    • - {% endfor %} - {% else %} -
    • 暂无数据
    • - {% endif %} -
    -
    - -
    - -
    -
    -
    -
    - -{% endblock %} \ No newline at end of file diff --git a/utils/upload_to.py b/utils/upload_to.py index f2abe3c..2e59d00 100644 --- a/utils/upload_to.py +++ b/utils/upload_to.py @@ -50,8 +50,8 @@ def upload_image_and_rename(instance, filename): file_obj = None # 遍历 instance 的所有属性,找到第一个 FileField 类型的值 for field in instance._meta.get_fields(): - if hasattr(field, 'upload_to') and hasattr(instance, field.name): - val = getattr(instance, field.name) + if hasattr(field, 'upload_to') and hasattr(instance, field.title): + val = getattr(instance, field.title) if val and hasattr(val, 'chunks'): # 确认是文件对象 file_obj = val break @@ -79,8 +79,8 @@ def upload_file_and_rename(instance, filename): file_obj = None # 同样的通用查找逻辑 for field in instance._meta.get_fields(): - if hasattr(field, 'upload_to') and hasattr(instance, field.name): - val = getattr(instance, field.name) + if hasattr(field, 'upload_to') and hasattr(instance, field.title): + val = getattr(instance, field.title) if val and hasattr(val, 'chunks'): file_obj = val break