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
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().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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With