Hide fields in Django admin

2019-04-08 23:38发布

问题:

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

回答1:

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.



回答2:

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 {}


回答3:

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)


回答4:

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)


回答5:

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.