Django Advanced models


Example

A model can provide a lot more information than just the data about an object. Let's see an example and break it down into what it is useful for:

from django.db import models
from django.urls import reverse
from django.utils.encoding import python_2_unicode_compatible

@python_2_unicode_compatible
class Book(models.Model):
    slug = models.SlugField()
    title = models.CharField(max_length=128)
    publish_date = models.DateField()

    def get_absolute_url(self):
        return reverse('library:book', kwargs={'pk':self.pk})

    def __str__(self):
        return self.title

    class Meta:
        ordering = ['publish_date', 'title']

Automatic primary key

You might notice the use of self.pk in the get_absolute_url method. The pkfield is an alias to the primary key of a model. Also, django will automatically add a primary key if it's missing. That's one less thing to worry and let you set foreign key to any models and get them easily.

Absolute url

The first function that is defined is get_absolute_url. This way, if you have an book, you can get a link to it without fiddling with the url tag, resolve, attribute and the like. Simply call book.get_absolute_url and you get the right link. As a bonus, your object in the django admin will gain a button "view on site".

String representation

Have a __str__ method let you use the object when you need to display it. For example, with the previous method, adding a link to the book in a template is as simple as <a href="{{ book.get_absolute_url }}">{{ book }}</a>. Straight to the point. This method also control what is displayed in the admin drop-down, for foreign key for example.

The class decorator let you define the method once for both __str__ and __unicode__ on python 2 while causing no issue on python 3. If you expect your app to run on both version, that's the way to go.

Slug field

The slug field is similar to a char field but accept less symbols. By default, only letters, numbers, underscores or hyphens. It is useful if you want to identify an object using a nice representation, in url for example.

The Meta class

The Meta class let us define a lot more of information on the whole collection of item. Here, only the default ordering is set. It is useful with the ListView object for example. It take an ideally short list of field to use for sorting. Here, book will be sorted first by publication date then by title if the date is the same.

Other frequents attributes are verbose_name and verbose_name_plural. By default, they are generated from the name of the model and should be fine. But the plural form is naive, simply appending an 's' to the singular so you might want to set it explicitly in some case.