from django.contrib import admin from django.utils.html import format_html from django.urls import reverse from django.utils.safestring import mark_safe from .models import Website, CrawlTask, CrawledContent, CrawlLog, SearchKeyword, MediaFile from .tasks import crawl_websites_task @admin.register(Website) class WebsiteAdmin(admin.ModelAdmin): list_display = ['name', 'region', 'url', 'is_active', 'created_at'] list_filter = ['region', 'is_active', 'created_at'] search_fields = ['name', 'url', 'region'] list_editable = ['is_active'] ordering = ['region', 'name'] @admin.register(CrawlTask) class CrawlTaskAdmin(admin.ModelAdmin): list_display = ['name', 'status', 'created_by', 'progress_display', 'created_at', 'completed_at'] list_filter = ['status', 'created_by', 'created_at'] search_fields = ['name', 'keywords'] readonly_fields = ['created_at', 'started_at', 'completed_at', 'progress_display'] filter_horizontal = ['websites'] actions = ['execute_crawl_task'] def progress_display(self, obj): """显示任务进度""" if obj.status == 'completed': color = 'green' elif obj.status == 'failed': color = 'red' elif obj.status == 'running': color = 'orange' else: color = 'gray' return format_html( '{}%', color, f'{obj.progress_percentage:.1f} ({obj.crawled_pages}/{obj.total_pages})' ) progress_display.short_description = '进度' def execute_crawl_task(self, request, queryset): """执行选中的爬取任务""" for task in queryset: # 更新任务状态为pending task.status = 'pending' task.save() # 异步执行爬取任务 crawl_websites_task.delay(task.id) self.message_user(request, f"已启动 {queryset.count()} 个爬取任务。") execute_crawl_task.short_description = "执行选中的爬取任务" @admin.register(CrawledContent) class CrawledContentAdmin(admin.ModelAdmin): list_display = ['title_short', 'website', 'task', 'keywords_matched', 'media_count', 'publish_date', 'is_local_saved', 'created_at'] list_filter = ['website', 'task', 'created_at', 'publish_date', 'is_local_saved'] search_fields = ['title', 'content', 'keywords_matched'] readonly_fields = ['created_at', 'preview_content', 'media_files_display'] ordering = ['-created_at'] def title_short(self, obj): """显示缩短的标题""" return obj.title[:50] + '...' if len(obj.title) > 50 else obj.title title_short.short_description = '标题' def media_count(self, obj): """显示媒体文件数量""" count = obj.media_files.count() if count > 0: return format_html( '{}', count ) return "0" media_count.short_description = '媒体文件' def preview_content(self, obj): """预览内容""" if obj.is_local_saved: url = reverse('admin:crawled_content_preview', args=[obj.id]) return format_html( '预览文章', url ) elif obj.content: return format_html( '