How do I create a slug in Django?
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)
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'
A small correction to Thepeer's answer: To override save()
function in model classes, better add arguments to it:
from django.utils.text import slugifydef 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).