Fields

StatusField

A simple convenience for giving a model a set of “states.” StatusField is a CharField subclass that expects to find a class attribute called STATUS on its model or you can pass choices_name to use a different attribute name, and uses that as its choices. Also sets a default max_length of 100, and sets its default value to the first item in the STATUS choices:

from model_utils.fields import StatusField
from model_utils import Choices

class Article(models.Model):
    STATUS = Choices('draft', 'published')
    # ...
    status = StatusField()

(The STATUS class attribute does not have to be a Choices instance, it can be an ordinary list of two-tuples).

Using a different name for the model’s choices class attribute

from model_utils.fields import StatusField
from model_utils import Choices

class Article(models.Model):
    ANOTHER_CHOICES = Choices('draft', 'published')
    # ...
    another_field = StatusField(choices_name='ANOTHER_CHOICES')

StatusField does not set db_index=True automatically; if you expect to frequently filter on your status field (and it will have enough selectivity to make an index worthwhile) you may want to add this yourself.

MonitorField

A DateTimeField subclass that monitors another field on the model, and updates itself to the current date-time whenever the monitored field changes:

from model_utils.fields import MonitorField, StatusField

class Article(models.Model):
    STATUS = Choices('draft', 'published')

    status = StatusField()
    status_changed = MonitorField(monitor='status')

(A MonitorField can monitor any type of field for changes, not only a StatusField.)

If a list is passed to the when parameter, the field will only update when it matches one of the specified values:

from model_utils.fields import MonitorField, StatusField

class Article(models.Model):
    STATUS = Choices('draft', 'published')

    status = StatusField()
    published_at = MonitorField(monitor='status', when=['published'])

SplitField

A TextField subclass that automatically pulls an excerpt out of its content (based on a “split here” marker or a default number of initial paragraphs) and stores both its content and excerpt values in the database.

A SplitField is easy to add to any model definition:

from django.db import models
from model_utils.fields import SplitField

class Article(models.Model):
    title = models.CharField(max_length=100)
    body = SplitField()

SplitField automatically creates an extra non-editable field _body_excerpt to store the excerpt. This field doesn’t need to be accessed directly; see below.

Accessing a SplitField on a model

When accessing an attribute of a model that was declared as a SplitField, a SplitText object is returned. The SplitText object has three attributes:

content:

The full field contents.

excerpt:

The excerpt of content (read-only).

has_more:

True if the excerpt and content are different, False otherwise.

This object also has a __unicode__ method that returns the full content, allowing SplitField attributes to appear in templates without having to access content directly.

Assuming the Article model above:

>>> a = Article.objects.all()[0]
>>> a.body.content
u'some text\n\n<!-- split -->\n\nmore text'
>>> a.body.excerpt
u'some text\n'
>>> unicode(a.body)
u'some text\n\n<!-- split -->\n\nmore text'

Assignment to a.body is equivalent to assignment to a.body.content.

Note

a.body.excerpt is only updated when a.save() is called

Customized excerpting

By default, SplitField looks for the marker <!-- split --> alone on a line and takes everything before that marker as the excerpt. This marker can be customized by setting the SPLIT_MARKER setting.

If no marker is found in the content, the first two paragraphs (where paragraphs are blocks of text separated by a blank line) are taken to be the excerpt. This number can be customized by setting the SPLIT_DEFAULT_PARAGRAPHS setting.

UUIDField

A UUIDField subclass that provides an UUID field. You can add this field to any model definition.

With the param primary_key you can set if this field is the primary key for the model, default is True.

Param version is an integer that set default UUID version. Versions 1,3,4 and 5 are supported, default is 4.

If editable is set to false the field will not be displayed in the admin or any other ModelForm, default is False.

from django.db import models
from model_utils.fields import UUIDField

class MyAppModel(models.Model):
    uuid = UUIDField(primary_key=True, version=4, editable=False)

UrlsafeTokenField

A CharField subclass that provides random token generating using python’s secrets.token_urlsafe as default value.

If editable is set to false the field will not be displayed in the admin or any other ModelForm, default is False.

max_length specifies the maximum length of the token. The default value is 128.

from django.db import models
from model_utils.fields import UrlsafeTokenField


class MyAppModel(models.Model):
    uuid = UrlsafeTokenField(editable=False, max_length=128)

You can provide your custom token generator using the factory argument. factory should be callable. It will raise TypeError if it is not callable. factory is called with max_length argument to generate the token, and should return a string of specified maximum length.

import uuid

from django.db import models
from model_utils.fields import UrlsafeTokenField


def _token_factory(max_length):
    return uuid.uuid4().hex


class MyAppModel(models.Model):
    uuid = UrlsafeTokenField(max_length=32, factory=_token_factory)