Wiki

Clone wiki

django-autoslug / Home

AutoSlugField

AutoSlugField is an extended SlugField able to automatically resolve name clashes.

NOTE: please read the documentation. This wiki may be out of date.

Purpose

AutoSlugField can perform the following tasks on model save:

  • populate itself from another field (using populate_from),
  • use custom slugify function (can be defined in Settings), and
  • preserve uniqueness of the value (using unique or unique_with).

None of the tasks is mandatory, i.e. you can have auto-populated non-unique fields, manually entered unique ones (absolutely unique or within a given date) or both.

Uniqueness is preserved by checking if the slug is unique with given constraints (unique_with) or globally (unique) and adding a number to the slug to make it unique.

Installation

$ sudo easy_install django-autoslug

That's all, now you can import and use the field (see examples).

If you wish to test the whole project using $ python manage.py test, you should add "autoslug" to settings.INSTALLED_APPS.

Latest version

The development version can be installed from source:

$ hg clone http://bitbucket.org/neithere/django-autoslug/
$ cd django-autoslug
$ sudo python setup.py install

Please note that this version may be unstable.

Options

  • populate_from – string or callable: if string is given, it is considered as the name of attribute from which to fill the slug. If callable is given, it should accept instance parameter and return a value to fill the slug with.
  • unique – boolean: ensure total slug uniqueness (unless more precise unique_with is defined).
  • unique_with – string or tuple of strings: name or names of attributes to check for “partial uniqueness”, i.e. there will not be two objects with identical slugs if these objects share the same values of given attributes. For instance, unique_with='pub_date' tells AutoSlugField to enforce slug uniqueness of all items published on given date. The slug, however, may reappear on another date. If more than one field is given, e.g. unique_with=('pub_date', 'author'), then the same slug may reappear within a day or within some author’s articles but never within a day for the same author.

Note on fields order

Always place any slug attribute after attributes referenced by it (i.e. those from which you wish to populate_from or check unique_with). The reasoning is that autosaved dates and other such fields must be already processed before using them in the AutoSlugField.

Example usage:

from django.db import models
from autoslug.fields import AutoSlugField

class Article(models.Model):
    '''
    An article with title, date and slug. The slug is not totally
    unique but there will be no two articles with the same slug within
    any month.
    '''
    title = models.CharField(max_length=200)
    pub_date = models.DateField(auto_now_add=True)
    slug = AutoSlugField(populate_from='title', unique_with='pub_date__month')

More options:

# slugify but allow non-unique slugs
slug = AutoSlugField()

# globally unique, silently fix on conflict ("foo" --> "foo-1".."foo-n")
slug = AutoSlugField(unique=True)

# autoslugify value from attribute named "title"; editable defaults to False
slug = AutoSlugField(populate_from='title')

# same as above but force editable=True
slug = AutoSlugField(populate_from='title', editable=True)

# ensure that slug is unique with given date (not globally)
slug = AutoSlugField(unique_with='pub_date')

# ensure that slug is unique with given date AND category
slug = AutoSlugField(unique_with=('pub_date','category'))

# mix above-mentioned behaviour bits
slug = AutoSlugField(populate_from='title', unique_with='pub_date')

# minimum date granularity is shifted from day to month
slug = AutoSlugField(populate_from='title', unique_with='pub_date__month')

# autoslugify value from a dynamic attribute (i.e. a method)
slug = AutoSlugField(populate_from='get_full_name')

# autoslugify value from a custom callable
# (ex. usage: user profile models)
slug = AutoSlugField(populate_from=lambda instance: instance.user.get_full_name())

Updated