Creating a unique slug

If you are going to be the only one posting, it is probably safe for you to add the date to your post. This wont work if you have two posts with the same title on the same day, which for a small site is unlikly.

In both cases, you will need to have CharField rather than SlugField as / is not a SlugField safe character when using the Django admin.

/2009/01/30/the-slug.html

Code

from django.template.defaultfilters import slugify
import datetime

def save(self):
    super(ClassName, self).save()
    date = datetime.date.today()
    self.slug = '%i/%i/%i/%s' % (
        date.year, date.month, date.day, slugify(self.title)
    )
    super(ClassName, self).save()

The second way, which you can also merge with the first add the id as the suffix.

/2009/01/30/1-the-slug.html
or    
/1-the-slug.html

Code

from django.template.defaultfilters import slugify
import datetime

def save(self):
    super(ClassName, self).save()
    date = datetime.datetime.today()
    self.slug = '%i/%i/%i/%i-%s' % (
        date.year, date.month, date.day, self.id, slugify(self.title)
    )
    super(ClassName, self).save()

or

    self.slug = '%i-%s' % (
        self.id, slugify(self.title)
    )

You may need to change your URL matching Regular Expression. The following matches everything up to a dot. This wont work unless you have a file extensions, you could just match to the end of the string.

'^hints\-and\-tips/(?P<slug>[^\.]+)\.html$'

Note: Setting a Primary field yourself means id probably won't exist.

Comments

Posted by modocache on 27th Mar 2011 22:24

Very useful! Thanks!

Posted by limist on 6th May 2011 14:41

The combination of a title and date may usually be unique, but two things to consider are: 1) the slug becomes ugly and defeats the purpose of a slug (to be human-readable/meaningful) and 2) there are many other more general situations requiring a more robust slug strategy.

Take a look at this ticket, http://code.djangoproject.com/wiki/SlugifyUniquely

And also look at django-autoslug: https://bitbucket.org/neithere/django-autoslug

Posted by un33k on 1st Oct 2011 02:27

Yep, I agree, there are more elegant way to slugify and guarantee uniqueness.

Here is one that guarantees unicode as well well an uniqueness.

https://github.com/un33k/django-uuslug