How do I create a slug in Django?
Solution 1:
You will need to use the slugify function.
>>> from django.template.defaultfilters import slugify
>>> slugify("b b b b")
u'b-b-b-b'
>>>
You can call slugify
automatically by overriding the save
method:
class Test(models.Model):
q = models.CharField(max_length=30)
s = models.SlugField()
def save(self, *args, **kwargs):
self.s = slugify(self.q)
super(Test, self).save(*args, **kwargs)
Be aware that the above will cause your URL to change when the q
field is edited, which can cause broken links. It may be preferable to generate the slug only once when you create a new object:
class Test(models.Model):
q = models.CharField(max_length=30)
s = models.SlugField()
def save(self, *args, **kwargs):
if not self.id:
# Newly created object, so set slug
self.s = slugify(self.q)
super(Test, self).save(*args, **kwargs)
Solution 2:
There is corner case with some utf-8 characters
Example:
>>> from django.template.defaultfilters import slugify
>>> slugify(u"test ąęśćółń")
u'test-aescon' # there is no "l"
This can be solved with Unidecode
>>> from unidecode import unidecode
>>> from django.template.defaultfilters import slugify
>>> slugify(unidecode(u"test ąęśćółń"))
u'test-aescoln'
Solution 3:
A small correction to Thepeer's answer: To override save()
function in model classes, better add arguments to it:
from django.utils.text import slugify
def save(self, *args, **kwargs):
if not self.id:
self.s = slugify(self.q)
super(test, self).save(*args, **kwargs)
Otherwise, test.objects.create(q="blah blah blah")
will result in a force_insert
error (unexpected argument).
Solution 4:
If you're using the admin interface to add new items of your model, you can set up a ModelAdmin
in your admin.py
and utilize prepopulated_fields
to automate entering of a slug:
class ClientAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('name',)}
admin.site.register(Client, ClientAdmin)
Here, when the user enters a value in the admin form for the name
field, the slug
will be automatically populated with the correct slugified name
.