在Django管理员中隐藏字段

8

我试图通过设置editable=False在管理员中隐藏我的slug字段,但每次这样做时,我都会收到以下错误:

KeyError at /admin/website/program/6/
Key 'slug' not found in Form
Request Method: GET
Request URL:    http://localhost:8000/admin/website/program/6/
Exception Type: KeyError
Exception Value:    
Key 'slug' not found in Form
Exception Location: c:\Python26\lib\site-packages\django\forms\forms.py in __getitem__, line 105
Python Executable:  c:\Python26\python.exe
Python Version: 2.6.4

有什么想法为什么会发生这种情况?

请问您能展示一下您的模型、表单和视图吗? - Brant
我把它们放在dpaste上了http://dpaste.com/186243/ - jwesonga
5个回答

11

我不能确定你的具体错误,但这对我有效...

from django.template.defaultfilters import slugify
# Create your models here.

class Program(models.Model):
    title=models.CharField(max_length=160,help_text="title of the program")
    description=models.TextField(help_text="Description of the program")
    slug=models.SlugField(max_length=160,blank=True,editable=False)

    def __unicode__ (self):
        return self.title

    class Meta:
        verbose_name="KCDF Program"
        verbose_name_plural="KCDF Programs"

    def save(self):
        self.slug = slugify(self.title)
        super(Program,self).save()

    def get_absolute_url(self):
        return "/program/%s/" % self.slug

当模型被保存时,这将为你创建一个slug字段。

在ModelAdmin中省略自动填充功能即可。

我在管理界面上运行这个功能时没有任何问题。


尝试了一下,它成功了!我认为 prepopulated_fields = {"slug": ("title",)} 是问题所在,一旦我将其移除并使用上述示例重构我的模型,它就可以工作了。我能够在 modelAdmin 中添加 exclude('slug',) 并将其从用户隐藏。 - jwesonga

6

我的解决方案不仅隐藏了slug字段,还允许在未保存时更改slug。问题在于,在prepopulated_fields中使用的字段必须在表单中,但如果是只读的,则不存在。这个问题可以通过只在没有设置只读属性时设置prepopulated_fields来解决。

class ContentAdmin(admin.ModelAdmin):
    def get_readonly_fields(self, request, obj=None):
        if obj:
            return ('slug',)
        return ()
    def get_prepopulated_fields(self, request, obj=None):
        if not obj:
            return {'slug': ('title',)}
        return {}

4

建议在具有额外参数的模型上执行自定义保存方法。

因此,代码应该像下面这样:

def save(self, *args, **kwargs):
    self.slug = slugify(self.title)
    super(YourModel, self).save(*args, **kwargs)

4

不要使用editable=False,而是在管理后台中隐藏它们:

from django.contrib import admin

class MyModelAdmin(admin.ModelAdmin):
    exclude = ('slug',)

您可以通过在models.py中使用以下方式的slugify,使得slug使用您的模型的“名称”字段(或其他您想要的字段)保存,并且仅在创建该实例时保存一次:
from django.template.defaultfilters import slugify

class MyModel(models.Model):
# model fields
...
    def save(self, *args, **kwargs):
        if not self.id:
            self.slug = slugify(self.name)

        super(Product, self).save(*args, **kwargs)

1
我知道这是一个非常老的问题,但我写这篇文章是为了未来的参考。
如果你只想使用CSS在管理站点中隐藏某些内容,可以使用任何已经具有“display:none”或类似属性的类。
在Django 1.6.5的forms.css文件中,你可以找到:
.empty-form {
    display: none;
}

因此,在您的字段集中,使用 empty-form 类添加一个隐藏字段组,如下所示:

fieldsets = [
        [_('Visible class'), {
            'classes' : ['any class for them',],
            'description' : '',
            'fields' : [['visible fields 1',],
                        ['visible fields 2',],
            ],
        }],
        [None, {
            'classes' : ['empty-form',],
            'fields' : ['hidden fields here',],
        }],
    ]

在我的情况下,我正在使用grappelli,所以我使用ui-helper-hidden类代替。

祝你有美好的一天。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接