AutoSlugField is an extended SlugField able to automatically resolve name clashes.
AutoSlugField can also perform the following tasks on save:
- populate itself from another field (using populate_from),
- use custom slugify function (using slugify or 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.
- always_update – boolean: if True, the slug is updated each time the model instance is saved. Use with care because cool URIs don’t change (and the slug is usually a part of object’s URI). Note that even if the field is editable, any manual changes will be lost when this option is activated.
- 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.
- sep – string: if defined, overrides default separator for automatically incremented slug index (i.e. the “-” in “foo-2”).
- slugify – callable: if defined, overrides AUTOSLUG_SLUGIFY_FUNCTION defined in Settings.
- 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. Foreign keys are also supported, i.e. not only unique_with=’author’ will do, but also unique_with=’author__name’.
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.
from django.db import models from autoslug 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')
# 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')) # ensure that slug is unique with an external object # assuming that author=ForeignKey(Author) slug = AutoSlugField(unique_with='author') # ensure that slug is unique with a subset of external objects (by lookups) # assuming that author=ForeignKey(Author) slug = AutoSlugField(unique_with='author__name') # 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()) # specify model manager for looking up slugs shared by subclasses 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. ''' objects = models.Manager() title = models.CharField(max_length=200) slug = AutoSlugField(populate_from='title', unique_with='pub_date__month', manager=objects) class NewsArticle(Article): pass # autoslugify value using custom `slugify` function from autoslug.settings import slugify as default_slugify def custom_slugify(value): return default_slugify(value).replace('-', '_') slug = AutoSlugField(slugify=custom_slugify)
Return enough information to recreate the field as a 4-tuple:
- The name of the field on the model, if contribute_to_class() has been run.
- The import path of the field, including the class:e.g. django.db.models.IntegerField This should be the most portable version, so less specific may be better.
- A list of positional arguments.
- A dict of keyword arguments.
Note that the positional or keyword arguments must contain values of the following types (including inner values of collection types):
- None, bool, str, int, float, complex, set, frozenset, list, tuple, dict
- datetime.datetime (naive), datetime.date
- top-level classes, top-level functions - will be referenced by their full import path
- Storage instances - these have their own deconstruct() method
This is because the values here must be serialized into a text format (possibly new Python code, possibly JSON) and these are the only types with encoding handlers defined.
There’s no need to return the exact way the field was instantiated this time, just ensure that the resulting field is the same - prefer keyword arguments over positional ones, and omit parameters with their default values.
Return field’s value just before saving.
Returns a suitable description of this field for South.