Django Administration Change list


Let's say you have a simple myblog app with the following model:

from django.conf import settings
from django.utils import timezone

class Article(models.Model):
    title = models.CharField(max_length=70)
    slug = models.SlugField(max_length=70, unique=True)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, models.PROTECT)
    date_published = models.DateTimeField(
    is_draft = models.BooleanField(default=True)
    content = models.TextField()

Django Admin's "change list" is the page that lists all objects of a given model.

from django.contrib import admin
from myblog.models import Article

class ArticleAdmin(admin.ModelAdmin):

By default, it will use the __str__() method (or __unicode__() if you on python2) of your model to display the object "name". This means that if you didn't override it, you will see a list of articles, all named "Article object". To change this behavior, you can set the __str__() method:

class Article(models.Model):
    def __str__(self):
        return self.title

Now, all your articles should have a different name, and more explicit than "Article object".

However you may want to display other data in this list. For this, use list_display:

class ArticleAdmin(admin.ModelAdmin):
    list_display = ['__str__', 'author', 'date_published', 'is_draft']

list_display is not limited to the model fields and properties. it can also be a method of your ModelAdmin:

from django.forms.utils import flatatt
from django.urls import reverse
from django.utils.html import format_html

class ArticleAdmin(admin.ModelAdmin):
    list_display = ['title', 'author_link', 'date_published', 'is_draft']
    def author_link(self, obj):
        author =
        opts = author._meta
        route = '{}_{}_change'.format(opts.app_label, opts.model_name)
        author_edit_url = reverse(route, args=[])
        return format_html(
            '<a{}>{}</a>', flatatt({'href': author_edit_url}), author.first_name)

    # Set the column name in the change list
    author_link.short_description = "Author"
    # Set the field to use when ordering using this column
    author_link.admin_order_field = 'author__firstname'