By Valery Melou on Jan 24, 2021

The Django administration site: One of the reasons why I love Django

My developer friends call me “Django boy”. This is because, whenever we have to start working on a new project, I consider Django first. And even if we don’t end up using Django for the project, I will explain to them how some features could have been implemented using Django. The thing is, I fell in love with Django from the first time I tried it. There were a lot of reasons but the most important for me back then was the built in administration site.

Home navbar

The Django administration

Before trying Django back in 2015, I had used only PHP frameworks like Symfony, Laravel and Codeigniter. One difficulty I had with those was to populate my database so that I could test the interfaces in the early stages of the project. They didn’t provide a way to do that in a graphical user interface. So one had to insert and update data in the database using raw SQL queries or fixtures. Later on, they had some third party projects like Sonata Admin for Symfony that allowed you to add an administration site to your project. But yes, you had to install additional packages in your project and spend a lot of time configuring them.

With Django, it wasn’t the case and it is still not the case. The project that is generated by the command django-admin startproject will create for you a project with the Django administration site already configured and ready to use. All you have to do is create your model just as usual, and then register them in the admin.

Let’s take an example. To follow along, you will need to have Python and Django installed on your computer. You also need to have some basic understanding of programming as this is not a tutorial on Django nor the Django administration site. We are going to create a project, add a model and register that model with Django admin so that we can populate the table represented by the model from the admin interface.

If you don’t have Django yet, please follow these instructions.

Creating a Django project

First make sure django is correctly installed by running the command below in your terminal.

> python -m django --version

This will show you the version of your Django installation if it was correctly installed.

To start a new Django project using your terminal, navigate to the folder where you want to create the project then run the command

> django-admin startproject website

where website is the name of the project you want to create, without any space. This will create a website directory in your current directory. Its structure will look like what is presented below:

📦website

┣ 📂website

┃ ┣ 📜asgi.py

┃ ┣ 📜settings.py

┃ ┣ 📜urls.py

┃ ┣ 📜wsgi.py

┃ ┗ 📜init.py

┗ 📜manage.py

I won’t go in the details of each file since it is out of the scope for this article but you can learn more about them in the Django documentation.

Creating a model

A Django project is made of applications which are just ways to isolate functionalities in modules. Every model needs to be part of an application. So let's create the application that will contain our model. Change your directory to the one containing your project files (website in my case) and run the command bellow:

> python manage.py startapp blog

This will create another folder called blog in your project root directory. This folder will have some files in it, including a file named models.py. It’s in that file we are going to create our model. So open the file, delete all its content, paste the code below in there and save it:

# blog/models.py

from django.db import models

class Post(models.Model):
  title = models.CharField(max_length=200)
  slug = models.SlugField()
  abstract = models.TextField()
  content = models.TextField()
  created = models.DateTimeField(auto_now_add=True)
  is_published = models.BooleanField(default=False)

What this code does is define a new model called Post with the following properties: title, slug, abstract, content, created and is_published. Each of these properties have a specific type which tells Django what type of data they will contain. Now that we have our model, we can tell Django to create the table where instances of that model will be saved in our database. But before that, we need to tell Django about our new app. Open the settings.py file that is in the folder website. Search for INSTALLED_APPS in the file and modify its value to add blog at the end. You should now have something like this:

# website/settings.py

...
INSTALLED_APPS = [
  'django.contrib.admin',
  'django.contrib.auth',
  'django.contrib.contenttypes',
  'django.contrib.sessions',
  'django.contrib.messages',
  'django.contrib.staticfiles',
  'blog',
]
...

Other parts of the file have been hidden for brevity.

Now, to create migrations and create tables in the database, run the two commands below:

> python manage.py makemigrations
> python manage.py migrate

The table where our blog entries are going to be saved is now created in the database and we can register our model to the admin site.

Registering a model to the admin site

Now let’s add our brand new model to the Django admin so that we can start creating Posts in the admin. To do that, open the admin.py file in the blog app folder. Also delete its content and paste in the lines below then save the file:

# blog/admin.py
from django.contrib import admin
from .models import Post

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
  pass

These lines tell Django that we want to be able to create Posts from the admin interface. Let’s go through each of them separately:

from django.contrib import admin

First, import all the Django admin classes and functions into our admin file under the namespace admin.

from .models import Post

Then import our Post model from the models.py file where we created it.

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
  pass

Finally, tell Django that we want to edit Post instances in the admin and that we will configure the options available in the admin interface using the PostAdmin class. This step makes use of the register decorator from django.contrib.admin. This decorator takes as argument a model class that we want to manage in the admin interface (Post) and it is applied to an admin class that will specify how the instances of the model should be managed (PostAdmin). We don’t have options for the post admin class yet. That is why we just added the keyword pass in the class definition. From here, you can already use the admin interface to create posts. But you will need a user account for that. Go ahead and run the following command in the root of your project.

> python manage.py createsuperuser

Follow the instructions to set up a new superuser (user full access to the built in administration interface. For me it looked like this:

> python manage.py createsuperuser
Username (leave blank to use ‘valery’):
Email address: me@valerymelou.com
Password:
Password (again):
Superuser created successfully.

Now you can run the Django development server with the following command:

> python manage.py runserver

Check the output to know when your server is ready. It should output something like the following:

Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
January 17, 2021 - 22:53:38
Django version 3.0.10, using settings 'website.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.

Then open the address http://localhost:8000/admin . You will see the Django administration login page:

Django administration login page

Enter the username and the password of the user you created before then press enter. That’s it! You are in the admin interface.

Django administration home page

You can see our blog app is registered as another app called Authentication and authorization, which is enabled by default when you create a new Django project. If you click the link Posts under our blog app, you will see a page saying select post to change. Since we haven’t added a post yet, there’s no post to change. Let’s create a new one. Click on the Add post link at the top right of the page. You should now have a form like the one below, where you can add the details of the Post you want to create:

Create post form

Go ahead, fill the form and press the SAVE button at the bottom right of the page. This will create your post (if you filled the form correctly) and redirect you to the list page where you will now see your newly created post:

Django will display only one column in the list with the value Post object (id) where ID is the ID of the object in our posts table.. We can actually configure that behavior by changing specific properties in our PostAdmin class. Head to the next section to see how.

Admin options

The admin class that we decorated with the register decorator can help us customize how Django should manage our Post model in the admin. That class inherits from admin.ModelAdmin which defines the basic options that allowed our Post model to be manageable in the admin without any configuration. In this section, we will be changing some of these properties to customize how the model is handled in the admin.

List display

You can customize the fields of your model that should be displayed in the list view of the admin interface. By default, Django will use <model_name> object <model_id>. To change that we can override the list_display` property of our admin class like below:

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
  list_display = ["title", "slug", "created", "is_published"]

If you did that and saved the file, go ahead and reload the posts page in your browser. You will see that Django is now displaying the title, the slug, the creation date and the is published flag for all blog posts:

Posts list

List filter

Usually you will want to filter that list to display only posts that are published. With Django admin, you can configure that. Edit your admin class to add another property called list_filter like this:

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
  list_display = ["title", "slug", "created", "is_published"]
  list_filter = ["is_published", "created"]

When you save your changes and refresh the list page in the browser, you will see that Django added a filter section on the right of the list of posts. There you can filter your posts by their published status or by creation date:

Posts list

Now, what if you had a thousands posts and you wanted to find a single one among them using its title? Django admin has you covered. Just add the search_fields property to your admin class and specify the list of fields you want to be able to search in. Your file should look like this when done, depending on the fields you want to search in:

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
  list_display = ["title", "slug", "created", "is_published"]
  list_filter = ["is_published", "created"]
  search_fields = ["title", "content"]

This will add a search bar to your posts lists where you can find posts that the title or the content contents what you typed in the search box:

Posts list

Date hierarchy

You can also add breadcrumbs in the posts list with different dates when posts were created. For that, there is the date hierarchy property of the admin class. Edit yours to add it like here:

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
  list_display = ["title", "slug", "created", "is_published"]
  list_filter = ["is_published", "created"]
  search_fields = ["title", "content"]
  date_hierarchy = "created"

Your posts list should now look like this:

Posts list

Conclusion

These are the 4 options of the admin interface which I always configure for my models. There are a lot more you can find in the ModelAdmin options of the Django admin site documentation. This post shouldn’t be used as a tutorial on the Django administration interface but just a highlight of its various functionalities. Thank you for reading.