You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Django Admin中无法隐藏slug字段?排除slug字段触发KeyError的原因咨询

解决Django Admin中排除slug字段触发KeyError的问题

你遇到的这个KeyError本质是Admin配置里的两个设置冲突了:你同时用exclude=('slug',)把slug字段从表单中移除,又设置了prepopulated_fields = {'slug': ('title',)}让Admin自动填充slug字段。

为什么会冲突?

  • prepopulated_fields的作用是告诉Django Admin:在表单里给slug字段生成一个自动填充的输入框,它依赖于表单中必须存在slug字段。
  • 但exclude会把slug字段从Admin表单里彻底移除,这就导致Django Admin试图找到slug字段来设置自动填充逻辑时,找不到对应的字段,于是抛出了KeyError。

两种解决思路

根据你的需求选择对应的方案:

方案1:完全隐藏slug字段(无需手动填充)

如果你希望slug字段完全不在Admin表单中显示,而是通过代码自动生成(比如在模型保存时自动生成),那么:

  1. 删除prepopulated_fields = {'slug': ('title',)}这一行配置
  2. 保留exclude=('created_at','slug',)
  3. 记得在模型的save方法中添加自动生成slug的逻辑(避免slug字段为空报错):

修改后的models.py:

from django.db import models
from django.utils import timezone
from django.urls import reverse
from django.utils.text import slugify  # 导入slugify

class Post(models.Model):
    title= models.CharField(max_length=50,null=False,blank=False)
    content= models.TextField(max_length=2000,null=False,blank=False)
    image= models.ImageField( upload_to="post-img/")
    created_at=models.DateTimeField(default=timezone.now)
    author=models.CharField(max_length=50,null=True,blank=True)
    slug=models.SlugField(max_length=30)

    class Meta:
        verbose_name =("Post")
        verbose_name_plural =("Posts")

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse("PostDetail", kwargs={'slug': self.slug})

    def headline(self):
        return self.content[:50]+'...'
    
    # 添加自动生成slug的逻辑
    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        super().save(*args, **kwargs)

修改后的admin.py:

from django.contrib import admin
from .models import Post

class PostAdmin(admin.ModelAdmin):
    exclude=('created_at','slug',)
    list_display=['title','headline','author','created_at']

admin.site.register(Post,PostAdmin)

方案2:保留自动填充,但让slug字段只读

如果你还是想让Admin自动从title生成slug,但不想让用户编辑这个字段,那么:

  1. 不要用exclude移除slug字段
  2. 添加readonly_fields=('slug',)让字段只读
  3. 保留prepopulated_fields配置

修改后的admin.py:

from django.contrib import admin
from .models import Post

class PostAdmin(admin.ModelAdmin):
    exclude=('created_at',)
    readonly_fields=('slug',)  # 设置slug为只读
    list_display=['title','headline','author','created_at','slug']  # 可选:在列表页显示slug
    prepopulated_fields = {'slug': ('title',)}

admin.site.register(Post,PostAdmin)

内容的提问来源于stack exchange,提问作者El Houssain Sabri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 15:34:05