class Foo(models.Model):
title = models.CharField(max_length=20)
slug = models.SlugField()
Is there a built-in way to get the slug field to autopopulate based on the title? Perhaps in the Admin and outside of the Admin.
class Foo(models.Model):
title = models.CharField(max_length=20)
slug = models.SlugField()
Is there a built-in way to get the slug field to autopopulate based on the title? Perhaps in the Admin and outside of the Admin.
for Admin in Django 1.0 and up, you'd need to use
prepopulated_fields = {'slug': ('title',), }
in your admin.py
Your key in the prepopulated_fields dictionary is the field you want filled, and the value is a tuple of fields you want concatenated.
Outside of admin, you can use the slugify
function in your views. In templates, you can use the |slugify
filter.
There is also this package which will take care of this automatically: https://pypi.python.org/pypi/django-autoslug
Outside the admin, see this django snippet. Put it in your .save()
, and it'll work with objects created programmatically. Inside the admin, as the others have said, use prepopulated_fields
.
For pre-1.0:
slug = models.SlugField(prepopulate_from=('title',))
should work just fine
For 1.0, use camflan's
You can also use pre_save django signal to populate slug outside of django admin code. See Django signals documentation.
Ajax slug uniqueness validation will be useful too, see As-You-Type Slug Uniqueness Validation @ Irrational Exuberance
Thought I would add a complete and up-to-date answer with gotchas mentioned:
If you are only concerned about adding and updating data in the admin, you could simply use the prepopulated_fields attribute
class ArticleAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
admin.site.register(Article, ArticleAdmin)
If you have built your own server-rendered interface with forms, you could auto-populate the fields by using either the |slugify tamplate filter or the slugify utility when saving the form (is_valid).
The above solutions will only auto-populate the slugfield (or any field) when data is manipulated through those interfaces (the admin or a custom form). If you have an API, management commands or anything else that also manipulates the data you need to drop down to model-level.
django-autoslug provides the AutoSlugField-fields which extends SlugField and allows you to set which field it should slugify neatly:
class Article(Model):
title = CharField(max_length=200)
slug = AutoSlugField(populate_from='title')
The field uses pre_save and post_save signals to achieve its functionality so please see the gotcha text at the bottom of this answer.
The last option is to implement this yourself, which involves overriding the default save() method:
class Article(Model):
title = CharField(max_length=200)
slug = SlugField()
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Job, self).save(*args, **kwargs)
This is a common miss-understanding by beginners to Django. First you should know that the pre_save and post_save signals are directly related to the save()-method. Secondly the different ways to do bulk-updates in Django all circumvent the save()-method to achieve high performance, by operating directly on the SQL-layer. This means that for the example model used in solution 3 or 4 above:
To do bulk updates and still utilize code-level constraints the only solution is to iterate objects one by one and call its save()-method, which has drastically less performance than SQL-level bulk operations. You could of course use triggers in your database, though that is a totally different topic.
autoslug has worked quite well for me in the past. Although I've never tried using it with the admin app.