tags:

views:

218

answers:

5

Assume the following:

models.py

class Entry(models.Model):
    title = models.CharField(max_length=50)
    slug = models.CharField(max_length=50, unique=True)
    body = models.CharField(max_length=200)

admin.py

class EntryAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug':('title',)}

I want the slug to be pre-populated by the title, but I dont want the user to be able to edit it from the admin. I assumed that adding the fields=[] to the admin object and not including the slug would have worked, but it didnt. I also tried setting editable=False in the model, but that also didnt work (infact, stops the page from rendering).

Thoughts?

A: 

I'm not sure what you're asking for IS possible. Your best bet is probably to hide the slug from the admin interface completely by specifying your fieldsets, and than overriding the save method to copy the slug from the tile, and potentially slugifying it...

Douglas Mayle
A: 

This Django Snippet does what you want by defining a custom Read-Only Widget. So you define a custom editor for the field which in fact doesn't allow any editing.

Dave Webb
+3  A: 

For this particular case you can override your save method to slugify (it's built-in method, look at django source) the title and store it in slug field. Also from there you can easily check if this slug is indeed unique and change it somehow if it's not.

Consider this example:

def save(self):
    from django.template.defaultfilters import slugify

    if not self.slug:
        self.slug = slugify(self.title)

    super(Your_Model_Name,self).save()
Dmitry Shevchenko
I was hoping there was a built-in django facility to do this... guess not. Thanks!
ashchristopher
Don't forget to take **kwargs in your overridden save and pass them on to the super(...).save() call.
insin
A: 

This snippet gives you an AutoSlugField with exactly the behavior you are seeking, and adding it to your model is a one-liner.

Carl Meyer
A: 

In addition to overriding save to provide the generated value you want, you can also use the exclude option in your ModelAdmin class to prevent the field from being displayed in the admin:

class EntryAdmin(admin.ModelAdmin):
    exclude = ('slug',)
insin
This does not seem to work with a slug that is using prepopulation."cannot concatenate 'str' and 'list' objects"
ashchristopher