Add Search button
This commit is contained in:
112
core/admin.py
112
core/admin.py
@@ -9,33 +9,39 @@ 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', 'export_as_word']
|
||||
|
||||
actions = ['delete_selected_articles', 'delete_dongfangyancao_articles', 'export_as_csv', 'export_as_json',
|
||||
'export_as_word']
|
||||
|
||||
def delete_dongfangyancao_articles(self, request, queryset):
|
||||
"""一键删除东方烟草报的所有文章"""
|
||||
# 获取东方烟草报网站对象
|
||||
@@ -46,33 +52,34 @@ class ArticleAdmin(admin.ModelAdmin):
|
||||
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]
|
||||
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:
|
||||
@@ -86,11 +93,11 @@ class ArticleAdmin(admin.ModelAdmin):
|
||||
'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格式"
|
||||
|
||||
def export_as_word(self, request, queryset):
|
||||
@@ -110,19 +117,20 @@ class ArticleAdmin(admin.ModelAdmin):
|
||||
for article in queryset:
|
||||
# 添加文章标题
|
||||
doc.add_heading(article.title, level=1)
|
||||
|
||||
|
||||
# 添加文章元数据
|
||||
doc.add_paragraph(f"网站: {article.website.name}")
|
||||
doc.add_paragraph(f"URL: {article.url}")
|
||||
doc.add_paragraph(f"发布时间: {article.pub_date.strftime('%Y-%m-%d %H:%M:%S') if article.pub_date else 'N/A'}")
|
||||
doc.add_paragraph(
|
||||
f"发布时间: {article.pub_date.strftime('%Y-%m-%d %H:%M:%S') if article.pub_date else 'N/A'}")
|
||||
doc.add_paragraph(f"创建时间: {article.created_at.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
|
||||
|
||||
# 添加文章内容
|
||||
doc.add_heading('内容', level=2)
|
||||
# 简单处理HTML内容,移除标签并处理图片
|
||||
from bs4 import BeautifulSoup
|
||||
soup = BeautifulSoup(article.content, 'html.parser')
|
||||
|
||||
|
||||
# 处理内容中的图片
|
||||
for img in soup.find_all('img'):
|
||||
src = img.get('src', '')
|
||||
@@ -133,7 +141,7 @@ class ArticleAdmin(admin.ModelAdmin):
|
||||
from django.conf import settings
|
||||
import requests
|
||||
from io import BytesIO
|
||||
|
||||
|
||||
# 构建完整的图片路径
|
||||
if src.startswith('http'):
|
||||
# 网络图片
|
||||
@@ -148,13 +156,13 @@ class ArticleAdmin(admin.ModelAdmin):
|
||||
except Exception as e:
|
||||
# 如果添加图片失败,添加图片URL作为文本
|
||||
doc.add_paragraph(f"[图片: {src}]")
|
||||
|
||||
|
||||
# 移除原始img标签
|
||||
img.decompose()
|
||||
|
||||
|
||||
content_text = soup.get_text()
|
||||
doc.add_paragraph(content_text)
|
||||
|
||||
|
||||
# 添加媒体文件信息
|
||||
if article.media_files:
|
||||
doc.add_heading('媒体文件', level=2)
|
||||
@@ -164,7 +172,7 @@ class ArticleAdmin(admin.ModelAdmin):
|
||||
from django.conf import settings
|
||||
from io import BytesIO
|
||||
import requests
|
||||
|
||||
|
||||
full_path = os.path.join(settings.MEDIA_ROOT, media_file)
|
||||
if os.path.exists(full_path):
|
||||
# 添加图片到文档
|
||||
@@ -179,44 +187,46 @@ class ArticleAdmin(admin.ModelAdmin):
|
||||
doc.add_paragraph(media_file)
|
||||
except Exception as e:
|
||||
doc.add_paragraph(media_file)
|
||||
|
||||
|
||||
# 添加分页符
|
||||
doc.add_page_break()
|
||||
|
||||
|
||||
# 保存到内存
|
||||
buffer = BytesIO()
|
||||
doc.save(buffer)
|
||||
buffer.seek(0)
|
||||
|
||||
|
||||
# 创建HttpResponse
|
||||
from django.http import HttpResponse
|
||||
response = HttpResponse(buffer.getvalue(), content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document')
|
||||
response = HttpResponse(buffer.getvalue(),
|
||||
content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document')
|
||||
response['Content-Disposition'] = 'attachment; filename=articles.docx'
|
||||
return response
|
||||
|
||||
|
||||
export_as_word.short_description = "导出选中文章为Word格式"
|
||||
|
||||
|
||||
# 为不同网站创建专门的文章管理类
|
||||
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 = []
|
||||
@@ -228,16 +238,16 @@ class NewsCnArticleAdmin(admin.ModelAdmin):
|
||||
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:
|
||||
@@ -251,43 +261,44 @@ class NewsCnArticleAdmin(admin.ModelAdmin):
|
||||
'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 = []
|
||||
@@ -299,16 +310,16 @@ class DongfangyancaoArticleAdmin(admin.ModelAdmin):
|
||||
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:
|
||||
@@ -322,16 +333,17 @@ class DongfangyancaoArticleAdmin(admin.ModelAdmin):
|
||||
'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)
|
||||
dongfangyancao_admin.register(Article, DongfangyancaoArticleAdmin)
|
||||
|
||||
Reference in New Issue
Block a user