Django 2.0.5 Admin面板无法访问草稿状态文章问题求助
首先,我注意到几个核心问题,这些正是导致你遇到404错误、Admin显示异常的主要原因:
1. Admin列表引用了不存在的模型字段
你的NewsAdmin类里的list_display包含了game、news_type、finish这些字段,但你的NewsModel根本没有定义这些字段!这会导致Django Admin渲染文章列表时抛出字段不存在的异常,表现出来就是文章(尤其是草稿)无法在Admin中显示,甚至直接导致Admin页面加载失败。
修复方法:
修改admin.py,只保留模型实际存在的字段,同时添加实用的Admin配置提升管理体验:
@admin.register(NewsModel) class NewsAdmin(admin.ModelAdmin): list_display = ('title', 'author', 'publish', 'status') # 仅保留模型存在的字段 list_filter = ('status', 'publish', 'author') # 添加状态、发布时间、作者的过滤栏 search_fields = ('title', 'body') # 支持按标题和内容搜索 prepopulated_fields = {'slug': ('title',)} # 在Admin编辑页实时生成slug
添加prepopulated_fields还能确保在Admin中创建文章时,slug自动根据标题生成,避免slug为空的问题。
2. Status字段缺少默认值,可能导致数据异常
你的NewsModel的status字段没有设置默认值,也未允许空白/空值。如果创建文章时没有明确指定状态(比如通过代码创建而非Admin),会导致status字段为空,这时候filter(status='draft')无法匹配到这些文章,但objects.all()仍然能查到它们,这就解释了你说的「文章列表视图能显示草稿,但草稿列表视图404」的矛盾现象。
修复方法:
给status字段添加默认值和允许空白的设置:
status = models.CharField( max_length=10, choices=STATUS_CHOICES, default='draft', # 默认创建为草稿 blank=True # 允许表单中不填(依赖默认值) )
3. 草稿文章的Slug可能存在生成异常
你的news_details视图通过slug查询文章,如果草稿文章的slug为空或者重复,就会触发get_object_or_404返回404。虽然你用了AutoSlugField,但偶尔可能会因为标题为空(尽管标题是必填字段)或其他原因导致slug生成失败。
排查与修复:
先通过Django Shell检查草稿文章的slug:
python manage.py shell
执行以下代码(替换为你的app名称):
from your_app_name.models import NewsModel drafts = NewsModel.objects.filter(status='draft') for draft in drafts: print(f"标题: {draft.title}, Slug: {draft.slug}")
如果发现slug为空,可以给模型添加自定义save方法确保slug生成:
from django.utils.text import slugify class NewsModel(models.Model): # ... 其他字段 ... def save(self, *args, **kwargs): # 如果slug为空,根据标题生成 if not self.slug: base_slug = slugify(self.title) self.slug = base_slug # 处理重复slug的情况 counter = 1 while NewsModel.objects.filter(slug=self.slug).exclude(id=self.id).exists(): self.slug = f"{base_slug}-{counter}" counter += 1 super().save(*args, **kwargs)
4. 草稿列表视图的分页逻辑存在潜在问题
当没有草稿文章时,你的分页逻辑会尝试访问不存在的页码,导致抛出异常进而触发404。
修复方法:
修改drafts视图的分页代码,处理空数据的情况:
def drafts(request): """ 所有草稿文章列表 """ news_list = NewsModel.objects.filter(status='draft') paginator = Paginator(news_list, 9) page = request.GET.get('page') try: news = paginator.page(page) except PageNotAnInteger: # 如果页码不是整数,返回第一页 news = paginator.page(1) except EmptyPage: # 如果页码超出范围,返回最后一页;如果没有数据,返回空分页对象 news = paginator.page(paginator.num_pages) if paginator.num_pages > 0 else paginator.page(1) return render(request, 'news/news_list.html', {'news': news, 'section': 'news', 'page': page})
5. URL配置的一致性问题
你的草稿列表URL是path('news/drafts', views.drafts, name='drafts'),没有结尾的斜杠。Django默认的APPEND_SLASH=True会导致访问/news/drafts/时自动重定向,但为了避免潜在的问题,建议统一添加斜杠:
path('news/drafts/', views.drafts, name='drafts'),
按照以上步骤修复后,你的草稿文章应该能正常在Admin中显示,也能通过草稿列表和详情视图访问了。
内容的提问来源于stack exchange,提问作者GotConfused

