from django.contrib import admin from django.contrib.admin import AdminSite from .models import Website, Article # 添加actions相关的导入 from django.contrib import messages from django.http import HttpResponseRedirect # 添加导出功能所需导入 import csv from django.http import HttpResponse import json # 创建自定义管理站点 class NewsCnAdminSite(AdminSite): site_header = "新华网管理后台" site_title = "新华网管理" index_title = "新华网内容管理" class DongfangyancaoAdminSite(AdminSite): site_header = "东方烟草报管理后台" site_title = "东方烟草报管理" index_title = "东方烟草报内容管理" # 实例化管理站点 news_cn_admin = NewsCnAdminSite(name='news_cn_admin') dongfangyancao_admin = DongfangyancaoAdminSite(name='dongfangyancao_admin') @admin.register(Website) class WebsiteAdmin(admin.ModelAdmin): list_display = ('name', 'base_url', 'enabled') # 为ArticleAdmin添加自定义动作 @admin.register(Article) class ArticleAdmin(admin.ModelAdmin): list_display = ('title', 'website', 'pub_date') search_fields = ('title', 'content') # 添加动作选项 actions = ['delete_selected_articles', 'delete_dongfangyancao_articles', 'export_as_csv', 'export_as_json'] def delete_dongfangyancao_articles(self, request, queryset): """一键删除东方烟草报的所有文章""" # 获取东方烟草报网站对象 try: dongfangyancao_website = Website.objects.get(name='东方烟草报') # 删除所有东方烟草报的文章 deleted_count = Article.objects.filter(website=dongfangyancao_website).delete()[0] self.message_user(request, f"成功删除 {deleted_count} 篇东方烟草报文章", messages.SUCCESS) except Website.DoesNotExist: self.message_user(request, "未找到东方烟草报网站配置", messages.ERROR) # 设置动作的显示名称 delete_dongfangyancao_articles.short_description = "删除所有东方烟草报文章" def export_as_csv(self, request, queryset): """导出选中的文章为CSV格式""" meta = self.model._meta field_names = [field.name for field in meta.fields] response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta) writer = csv.writer(response) writer.writerow(field_names) for obj in queryset: row = [getattr(obj, field)() if callable(getattr(obj, field)) else getattr(obj, field) for field in field_names] writer.writerow(row) return response export_as_csv.short_description = "导出选中文章为CSV格式" def export_as_json(self, request, queryset): """导出选中的文章为JSON格式""" response = HttpResponse(content_type='application/json') response['Content-Disposition'] = 'attachment; filename=articles.json' # 构造要导出的数据 articles_data = [] for article in queryset: articles_data.append({ 'id': article.id, 'title': article.title, 'website': article.website.name, 'url': article.url, 'pub_date': article.pub_date.strftime('%Y-%m-%d %H:%M:%S') if article.pub_date else None, 'content': article.content, 'created_at': article.created_at.strftime('%Y-%m-%d %H:%M:%S'), 'media_files': article.media_files }) # 写入JSON数据 response.write(json.dumps(articles_data, ensure_ascii=False, indent=2)) return response export_as_json.short_description = "导出选中文章为JSON格式" # 为不同网站创建专门的文章管理类 class NewsCnArticleAdmin(admin.ModelAdmin): list_display = ('title', 'pub_date') search_fields = ('title', 'content') list_filter = ('pub_date',) actions = ['export_as_csv', 'export_as_json'] def get_queryset(self, request): qs = super().get_queryset(request) # 只显示新华网的文章 return qs.filter(website__name='www.news.cn') def export_as_csv(self, request, queryset): """导出选中的文章为CSV格式""" meta = self.model._meta field_names = [field.name for field in meta.fields if field.name != 'content'] # 排除content字段以减小CSV大小 response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename=news_cn_articles.csv' writer = csv.writer(response) writer.writerow(field_names) for obj in queryset: row = [] for field in field_names: value = getattr(obj, field) if callable(value): value = value() if field == 'website': value = value.name row.append(value) writer.writerow(row) return response export_as_csv.short_description = "导出选中文章为CSV格式" def export_as_json(self, request, queryset): """导出选中的文章为JSON格式""" response = HttpResponse(content_type='application/json') response['Content-Disposition'] = 'attachment; filename=news_cn_articles.json' # 构造要导出的数据 articles_data = [] for article in queryset: articles_data.append({ 'id': article.id, 'title': article.title, 'website': article.website.name, 'url': article.url, 'pub_date': article.pub_date.strftime('%Y-%m-%d %H:%M:%S') if article.pub_date else None, 'content': article.content, 'created_at': article.created_at.strftime('%Y-%m-%d %H:%M:%S'), 'media_files': article.media_files }) # 写入JSON数据 response.write(json.dumps(articles_data, ensure_ascii=False, indent=2)) return response export_as_json.short_description = "导出选中文章为JSON格式" class DongfangyancaoArticleAdmin(admin.ModelAdmin): list_display = ('title', 'pub_date') search_fields = ('title', 'content') list_filter = ('pub_date',) # 添加动作选项 actions = ['delete_selected_articles', 'delete_all_articles', 'export_as_csv', 'export_as_json'] def get_queryset(self, request): qs = super().get_queryset(request) # 只显示东方烟草报的文章 return qs.filter(website__name='东方烟草报') def delete_all_articles(self, request, queryset): """删除当前筛选的所有文章(东方烟草报的所有文章)""" # 删除所有东方烟草报的文章 deleted_count = self.get_queryset(request).delete()[0] self.message_user(request, f"成功删除 {deleted_count} 篇文章", messages.SUCCESS) # 设置动作的显示名称 delete_all_articles.short_description = "删除所有当前筛选的文章" def export_as_csv(self, request, queryset): """导出选中的文章为CSV格式""" meta = self.model._meta field_names = [field.name for field in meta.fields if field.name != 'content'] # 排除content字段以减小CSV大小 response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename=dongfangyancao_articles.csv' writer = csv.writer(response) writer.writerow(field_names) for obj in queryset: row = [] for field in field_names: value = getattr(obj, field) if callable(value): value = value() if field == 'website': value = value.name row.append(value) writer.writerow(row) return response export_as_csv.short_description = "导出选中文章为CSV格式" def export_as_json(self, request, queryset): """导出选中的文章为JSON格式""" response = HttpResponse(content_type='application/json') response['Content-Disposition'] = 'attachment; filename=dongfangyancao_articles.json' # 构造要导出的数据 articles_data = [] for article in queryset: articles_data.append({ 'id': article.id, 'title': article.title, 'website': article.website.name, 'url': article.url, 'pub_date': article.pub_date.strftime('%Y-%m-%d %H:%M:%S') if article.pub_date else None, 'content': article.content, 'created_at': article.created_at.strftime('%Y-%m-%d %H:%M:%S'), 'media_files': article.media_files }) # 写入JSON数据 response.write(json.dumps(articles_data, ensure_ascii=False, indent=2)) return response export_as_json.short_description = "导出选中文章为JSON格式" # 在各自的管理站点中注册模型 news_cn_admin.register(Website, WebsiteAdmin) news_cn_admin.register(Article, NewsCnArticleAdmin) dongfangyancao_admin.register(Website, WebsiteAdmin) dongfangyancao_admin.register(Article, DongfangyancaoArticleAdmin)