In this chapter we will create our first database and use it to store messages from users which will be output on the homepage in a message board format. In the process we will explore Django’s built-in admin interface which provides a visual way to make changes to our data.

Complete source code can be found on Github.


Since we’ve already set up several Django projects at this point in the book, we can quickly run through our commands to begin a new one.

Create a new directory for our code:

$ mkdir ~/Desktop/message_board
$ cd ~/Desktop/message_board

Create a new virtual environment called mb:

$ python3 -m venv ~/.virtualenvs/mb
$ source ~/.virtualenvs/mb/bin/activate

Install Django and create a new Django project (don’t forget to include the period . at the end of the command):

(mb) $ pip install django
(mb) $ startproject mb_project .

And now set up our initial database by using the migrate command:

(mb) $ ./ migrate

If we look inside our directory with the ls command, we’ll see there’s a new file, db.sqlite3, a SQLite database Django just created.

(mb) $ ls
db.sqlite3 mb_project

Django provides built-in support for several types of databases but SQLite is ideal for small projects because it runs off a single file and requires no complex installation. Later in the book we will use a more advanced database, PostgreSQL, but for now SQLite is more than adequate.

To confirm everything works correctly, spin up our local server, noticing that unlike in previous chapters, there’s no error message anymore complaining about “unapplied migrations.”

(mb) $ ./ runserver

And navigate to in your browser. You should see the familiar “Welcome to Django page” in light-blue pastel.

Django welcome page

Create an app

Our message board app needs the ability to display messages on the homepage. We’ll create an app called message_app to do this. Quit the local server by running Control+c from the command line and then enter the following command:

(mb) $ ./ startapp message_app

And tell Django we’ve added a new app by updating the bottom section of INSTALLED_APPS in our mb_project/ file:

# mb_project/

    # my apps

Create a database model

Now we’ll define our database models so we can store and display information. For our relatively simple message board project we’ll only need one database model, but a real-world Django project will have multiple, complex database models.

Open the message_app/ file and look at default code which Django provides:

# message_app/
from django.db import models

# Create your models here

Django imports a module models to help us build new database models, which will “model” the characteristics of the data in our database. We want to create a model to store the textual content of a message board post. We can do so as follows:

# message_app/
from django.db import models

class Post(models.Model):
    text = models.TextField()

We’ve created a new database model called Post which has the database field text. We’ve also specified the type of content it will hold, TextField(). Django provides many model fields supporting common types of content such as characters, dates, integers, emails, and so on.

Activating models

Creating or modifying a database in Django is a two-step process. First we create a migration file with the makemigrations command, which can be thought of as a list of instructions for how to build the database. Then we build the actual database with the migrate command based on the migrations file.

Let’s make our first migration:

(mb) $ ./ makemigrations message_app
Migrations for 'message_app':
    - Create model Post

The result is a new migrations file, When we make future changes to our database structure, we will have new migrations files. This way we have a record of all our changes rather than destroying and recreating our database from scratch whenever we want to modify something.

To apply our migration to our database, use the migrate command. We’ve already used this once before to set up our initial database based on Django’s default settings.

(mb) $ ./ migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, message_app, sessions
Running migrations:
  Applying message_app.0001_initial... OK

Going forward, whenever we want to make a change to our database we will alter and then:

  • Create a new migrations with ./ makemigrations
  • Apply the migration to the database with ./ migrate

Django Admin

Django provides us with a robust admin interface for interacting with our database. To use it, we first need to create a superuser who can login. In your command line console, type ./ createsuperuser and respond to the prompts for a username, email, and password:

(mb) $ ./ createsuperuser
Username (leave blank to use 'wsv'): wsv
Password (again):
Superuser created successfully.

Note: When you type your password, it will not appear visible in the command line console for security reasons.

Restart the Django server with ./ runserver and in your browser go to You should see the admin’s login screen:

Admin login page

Login by entering the username and password you just created. You should see the Django admin homepage next:

Admin homepage

But where’s our message_app app? It’s not displayed on the main admin page!

We can change that by opening the message_app/ file and editing it to look like this:

# message_app/
from django.contrib import admin

from .models import Post

Django now knows that it should display our message_app app and its database model Post on the admin page. If you refresh your browser you’ll see that it now appears:

Admin homepage updated

Note that Django has automatically added an “s” onto the end of “Post” since there will be soon be multiple records within this model.

Now let’s create our first message board post for our database. Click on the + Add button opposite Post. Enter your own text in the Text form field.

Admin new entry

Then click the “Save” button, which will redirect you to the main Post page. However if you look closely, there’s a problem: our new entry is called “Post object”, which isn’t very helpful.

Admin new entry

Let’s change that. Within the message_app/ file, add a new function __str__ as follows:

# message_app/
from django.db import models

class Post(models.Model):
    text = models.TextField()

    def __str__(self):
        """A string representation of the model."""
        return self.text[:50]

If you refresh your Admin page in the browser, you’ll see it’s changed to a much more descriptive and helpful representation of our database entry.

Admin new entry

Much better! It’s important to add str() methods to all of your models to improve their readability.


In order to display our database content on our homepage, we have to wire up our views, templates, and URLConfs.

Let’s start with the view. Earlier in the book we used the built-in generic TemplateView to display a template file on our homepage. Now we want to list the contents of our database model. Fortunately this is a common task and can be done quite easily with the class-based view ListView.

In the message_app/ file enter the Python code below:

# message_app/
from django.views.generic import ListView
from .models import Post

class Home_page_view(ListView):
    model = Post
    template_name = 'message_app/index.html'

In the first line we’re importing ListView and in the second line we need to explicitly define which model we’re using. In the view, we can subclass ListView, specify our model name and specify our template reference. Internally ListView returns an object called object_list that we want to display in our template.

Quit out of the server with Control-c. Create a new templates directory structure and within it an index.html file:

(mb) $ mkdir message_app/templates
(mb) $ mkdir message_app/templates/message_app
(mb) $ touch message_app/templates/message_app/index.html

Using the Django Templating Language we can loop over object_list and display all our database posts as follows:

<!-- message_app/templates/message_app/index.html -->
<h1>Message board homepage</h1>
  {% for post in object_list %}
    <li>{{ post }}</li>
  {% endfor %}

Finally we need to set up our URLConfs. Create an app-level file:

(mb) $ touch message_app/

And then update it like so:

# message_app/
from django.conf.urls import url

from .views import Home_page_view

urlpatterns = [
    url(r'^$', Home_page_view.as_view()),

And update our project-level file:

# mb_project/
from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^', include('message_app.urls')),

Restart the server:

(mb) $ ./ runserver

Homepage with posts

It worked! We’re basically done at this point, but let’s create a few more message board posts in the Django admin to confirm that they’ll all display correctly on the homepage.

Adding new posts

To add new posts to our message board, go back into the Admin at and add two more posts. Here’s what mine look like:

Admin entry

Admin entry

Updated admin entries section

If you return to the homepage you’ll see it automatically displays our formatted posts. Woohoo!

Homepage with three entries


We’ve now built our first database-driven app. While it’s deliberately quite basic, now we know how to save information to a database, update it with the admin panel, and then display it on our web applications.

In the next chapter we’ll build a blog application that uses forms so users can create, edit, and delete posts. We’ll also add styling via CSS.

Continue on to Chapter 5: Blog app.

Sign up for the Django For Beginners newsletter for updates when new chapters are available and special discounts for the print edition of the book.