I'm tying to hide my slug fields in the admin by setting editable=False but every time I do that I get the following error:
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
Any idea why this is happening
I can't speak to your exact error but this worked for me...
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
That will whip you up a slug field when the model is saved.
Just leave out the auto-populate thing in the ModelAdmin.
I had that running in the admin without a problem.
My solution does not just hide the slug field, but allows changing the slug when not yet saved. The problem is that the fields used in prepopulated_fields
, must be in the form, but they aren't there if readonly. This is solved by only setting prepopulated_fields
if readonly is not set.
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 {}
It is advised to do custom save method on models WITH extra arguments.
So the code would like the following:
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(YourModel, self).save(*args, **kwargs)
Instead of using editable=False
just hide them in the admin:
from django.contrib import admin
class MyModelAdmin(admin.ModelAdmin):
exclude = ('slug',)
You can also make it so the slug saves using the "name" field of your model (or whatever field you want) and only saves once when you create that instance using slugify in the following way in your models.py:
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)
I know this is a very old question, but I write this for future references.
If you just want to hide something in the admin site using CSS, you can use any class which already has display:none
or similar.
In Django 1.6.5 forms.css you can find:
.empty-form {
display: none;
}
so in your fieldsets, add a group for hidden fields using empty-form class like this:
fieldsets = [
[_('Visible class'), {
'classes' : ['any class for them',],
'description' : '',
'fields' : [['visible fields 1',],
['visible fields 2',],
],
}],
[None, {
'classes' : ['empty-form',],
'fields' : ['hidden fields here',],
}],
]
In my case I'm using grappelli, so I use the ui-helper-hidden class instead
Have a good day.