An Introduction to Django – Part 7

This will be our last Introduction to Django post.  Here, we’ll look at customizing the admin site.  Next time, we’ll look at making our own Django app to help organize our grocery shopping list.

Customize The Admin Form

Changing The Order of Fields

Recall from Part 2 that we registered the Question model with within the polls/ file.  This allowed Django to automatically generate an admin site with a default form.

To customize this page, open the polls/ file and change it to this:

from django.contrib import admin

# Register your models here.
from .models import Question

class QuestionAdmin(admin.ModelAdmin):
    fields = ['pub_date', 'question_text'], QuestionAdmin)

Next, start the development server by navigating to the file and running the command

python runserver

Then, go to the admin tool at and navigate to change a question.  It should look like this:


The above change put the date published date before the question text.

Add Related Objects

Our questions can have multiple choices, but the Question admin page doesn’t display them.  We have a couple of ways to solve this.

First, open the polls/ file and register the Choice with the admin just like we did above for Question:

from django.contrib import admin

# Register your models here.
from .models import Question, Choice

class QuestionAdmin(admin.ModelAdmin):
    fields = ['pub_date', 'question_text'], QuestionAdmin)

Now, within the admin tool we see an option for Choices and Questions:


If we navigate within the Admin Tool to Choices – Add Choice we will see the following:


The dropdown contains all of our questions (for me, this is just “What’s up?”).  We can add one choice at a time to each question.  This is maybe better than how we were doing it before, but it would be much more efficient if we could add all of the choices when we add the actual question.

Within the polls/ file, remove the line

And make the file look like this:

from django.contrib import admin

from .models import Choice, Question

class ChoiceInline(admin.StackedInline):
    model = Choice
    extra = 3

class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
    inlines = [ChoiceInline], QuestionAdmin)

This lets Django know that we want to edit the Choice objects when we edit the Question within the admin page, and it gives us enough room to add 3 choices (this is defined by the extra variable).

Open the Add Question page and it should look like this:


Note that at the bottom of the Choices, you have the option to click a link to add more.  Pretty cool!

If you don’t like how much room this takes up, you can change the ChoiceInLine class within the polls/ file to be this instead:

class ChoiceInline(admin.TabularInLine):

This changes the Add Question page to look like this:


Customizing The Change List

The Change List is the page that shows all of our questions.  It looks like this for me:


Maybe we want to see more information about each question such as the date published and if it was published recently.

Open the polls/ file and add the following:

class QuestionAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question_text', 'pub_date', 'was_published_recently')

This will make the page look like this:


Django will automatically let you click on any of the columns to sort by that column.  We can change the names of the columns by adding attributes to the Question method within polls/  Open that file and add the following:

class Question(models.Model):
    # ...
    def was_published_recently(self):
        now =
        return now - datetime.timedelta(days=1) <= self.pub_date <= now
    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'

Additionally, edit the file and add:

class QuestionAdmin(admin.ModelAdmin):
    # ....
    list_filter = ['pub_date']

This will give us a filtering option.  Reload the Change List page and it should look like this:


Note that we only told it to filter by the publication date.  Django automatically knew that this datatype was a date type and added ‘Any Date’, ‘Today’, ‘Past 7 days’, etc.

Add a search field by adding the following to the QuestionAdmin class:

class QuestionAdmin(admin.ModelAdmin):
    # ....
    search_fields = ['question_text']

This will add a search bar near the top:


Customize the Admin Look and Feel

Customize Project Templates

Navigate to the project directory (where your file is located) and add a templates directory there.  For me, this is pantrio/templates.

Next, open your mysite/ file.  For me, this is pantrio/pantrio/  Look for the TEMPLATES variable (for me, it is on line 56) and add the following to the ‘DIRS’ option (for me, line 59):

'DIRS': [os.path.join(BASE_DIR, 'templates')],

Next, we need to figure out where our Django source code is so that we can copy a template from it.  Go to the command prompt and type:

python -c "import django; print(django.__path__)"

This will output where your Django lives.  For me, it is C:/Python27/Lib/site-packages/django

Navigate to this directory.  Then, go to contrib/admin/templates/admin and copy the base_site.html file.  Paste this file into your own app/templates/admin directory (for me this is pantrio/templates/admin).

Open this file and replace

{{ site_header|default:_('Django administration') }}

with the site’s name.  My base_site.html file looks like this:

{% extends "admin/base.html" %}

{% block title %}{{ title }} | {{ site_title|default:_('Blue Sheets') }}{% endblock %}

{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>
{% endblock %}

{% block nav-global %}{% endblock %}

This changes our Admin Pages from saying ‘Django Administration’, like this:


To whatever you set it to.  Like this:



That’s all for the Introduction to Django series.  I still feel like there are many things I don’t quite understand, but I am excited to try to jump in and make my own app!

Have questions or suggestions?  Please feel free to comment below or contact me.

Leave a Reply

Your email address will not be published. Required fields are marked *