Smartphone lying on a wood surface

Welcome to part 2 of 3 of my How to Build an App tutorial. In the first part, I explained how to create the back-end server which we will use to host our app’s back-end (if you didn’t get a chance to read it, you can check it out here). In this second part, I will explain exactly how to build the back-end itself.

If you’re loving this tutorial, then maybe you’ll like my course: How To Build A Backend with Python & Django REST Framework on Udemy!

How to Build an App Django REST Framework

How to Build an App Django REST Framework
If you haven’t gone through the steps in the first post yet, I suggest you do it now. If you really don’t feel like it, you can download the code from here and extract it to “c:\workspace”.

So, let’s start off by loading the development server using Vagrant. Open Command Prompt and switch to the “devenv” directory by typing:

cd c:\workspace\devenv

Next, run the following command to load vagrant:

vagrant up

After typing this, Vagrant should start booting the development server:

Vagrant Up Screenshot

The server may take 10 – 15 minutes to load. Then you should see something like this:

Vagrant Boot Complete Screenshot

Now that it’s loaded, let’s connect to the server by running the following:

vagrant ssh
Vagrant SSH Screenshot

Creating the Django Project and App

OK, now we are going to start our Django project. Switch back to the Command Line window that is connected to the server. Then change to the “/vagrant/project/” directory on the server by typing the following:

cd /vagrant/project/

This is the directory that is synced to “c:\workspace\devenv\project” on our system. In other words, anything you create in “/vagrant/project/” will appear in “c:\workspace\devenv\project” and vice versa.

Now we are going to switch to the Virtual Environment which we will use to install the packages we require. A “Virtual Environment” is an application that allows us to keep all of our Python packages for a particular project separate from other projects. If you want to learn more about Virtual Environments, you can read this:

Type the following command to activate the Virtual Environment “env”:

workon env

Now we are going to install the following packages into our Virtual Environment (I am pinning specific versions to future proof this article):

  • django
  • djangorestframework
  • mysqlclient

Note: There is a prerequisite for the Python mysqlclient package. It consists of one line in “/devenv/salt/dev.sls” and can be seen here: Make sure the line is added in your file. If it is not, then add it, and run the following on the server:

sudo salt-call state.highstate

Now run the following command to install the three python packages mentioned above:

pip install Django==1.9.4 djangorestframework==3.3.3 mysqlclient==1.3.7

Now let’s create our Django project. Make sure we are in the “/vagrant/project/”, and run the following command: startproject miab_backend

Let’s take a look at the “c:\workspace\devenv\project\” folder and you will see the files have been created:

miab_backend directory screenshot

Open the project file in as this is where we will be doing most of the upcoming work:

Opening miab_backend in Atom screenshot

Next, let’s create the Django app to store our API. Change to the miab_backend directory and start a new app called api by running the following commands:

cd /vagrant/project/miab_ backend/
python3 startapp api

If you look back to your project files in Atom, you will see that the app has been created:

Atom Project Files Screenshot

Setting up the Database Model

First, add the api app to the INSTALLED_APPS section of the file. Update it to look like this:


Now let’s setup the database. We must update the DATABASES section in the file. Update it to look like this:

    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'miab_db',
        'USER': 'root',
        'PASSWORD': 'password',

Now we need to create a database model in the api app to hold our messages. A database model effectively describes a database table (the name, columns, the data types). It allows us to easily interact with the database through Django.

Open the api/ file and update it to look like this:

# Import the 'models' package.
from django.db import models

# Create the class to describe the model.
class Message(models.Model):
    """Stores messages for our bottles."""

    # Create a text column to store the message. Limit this to 120
    # characters as we this isn't "Essey in a Bottle" :)
    message = models.CharField(max_length=120)
    # Add a boolean column for marking messages as read, so we can
    # filter them to ensure users only get new messages.
    is_read = models.BooleanField(default=False)

    # This is meta data about the database table.
    class Meta:
        # Set the table name.
        db_table = 'message'

    # Define what to output when the model is printed as a string.
    def __str__(self):
        # Return the message.
        return self.message

Comments (prefixed by #) describing what each line does are in-line.

Now, let’s create the migrations. Migrations are automatically generated Python files which describe changes in the database since the last “migration” was ran (which is never in our case). Let’s create the migrations for the above model by running the following from the Linux terminal:

python3 makemigrations

The migration files will be created:

Screenshot of Migration Files in Atom

Now we will run the migration. This will cause the necessary table to be created in the database to store our messages. Run the following:

python3 migrate

As this is the first time we are running the migrations, Django will apply a number of migrations from it’s core apps as well as ours:

Django migrations screenshot

Create the Admin Interface

Now we are going to create an admin interface for our back-end. We will do this using the Django Admin app, which comes pre-enabled with Django. To use this, all we need to do is tell the admin site to manage our model, and create a super user.

Tell the admin site to manage our messages model by opening the api/ file and updating it to look like this:

from django.contrib import admin
# Import our models module.
from . import models

# Register our "Message" model with the Django Admin/

Next, let’s create our superuser. This needs to be done on the command line, by typing the following command:

python3 createsuperuser

You will be prompted for a username, email address and password to be used for your admin user. Enter the details when prompted.

Now we are going to run the webserver and test our admin panel. However, before we do that, we need to find out what our server’s IP address is so we can access it. On the server, run the following command:

sudo ifconfig

In the output, you will see the details for two network interfaces called eth0 and eth1. We are interested in the inet addr for eth1. For me, it is, however, it may be different for you. Take note of your Server IP Address.

Server IP Address Screenshot

Taken note of your servers IP Address? Great! Now we are ready to start our server. Run the following command in the terminal to start the Django development web server:

python3 runserver <Server IP Address>:8000

Replace <server IP Address> with the IP address of your server. So for me, it would be:

python3 runserver

Now that the server is running, let’s load up a browser on your local machine and navigate to http://<Server IP Address>:8000/admin. So in my example, the address would be If all is working, you will be met with the Django Admin login screen:

Django Login Screen Screenshot

Enter your superuser credentials and click Log in:

Django administration login screenshot

Welcome to the wonderful Django admin which gives you an out-of-the-box administration panel for your application with only a few lines of code.

Let’s put our Django admin panel to immediate use by creating some example messages to kick off our Message in a Bottle application. Next to Messages click Add to add a new message:

Django Admin Messages Add screenshot

Now, type a message and click Save and add another.

Django Admin Enter Message Screenshot

Now, let’s repeat the above steps for 5 more messages, to add an element of randomness for our first few users. If you can’t think of any messages to add, here are a few examples:

  • When you have exhausted all possibilities, remember this: you haven’t.
  • Nothing worth having comes easy.
  • Your only limit is you.
  • A person who never made a mistake never tried anything new.
  • A river cuts through a rock, not because of its power, but its persistence.

After adding all those messages, click Messages in the breadcrumb navigation.

Django Admin Messages Screenshot

You will now see a list of all the messages you’ve added:Django Admin All Messages Screenshot

OK now that’s done, the database and admin panel is setup. Let’s move onto the next section.

Create the REST API

We now have a server, a database and an admin interface. The next step is to create a REST API which allows us to interact with our database.

Let’s start by enabling the Django REST Framework in our settings file. In the ‘miab_backend’ directory, edit the file. Locate the INSTALLED_APPS section and update it to look like this:


Next, let’s create our serailizer. The serializer’s job is to receive the user’s input and turn it into a Python object that we can work with in our application (and vice versa). The serializer has built-in functionality for input validation (eg. checking the user entered a string where a string is required).

In the ‘api’ directory, create a new file called Then input the following contents:

from rest_framework import serializers

from api import models

# The serializer class takes the users input and converts it to a Python
# object that we can work with (and vica versa).
class MessageSerializer(serializers.ModelSerializer):
    """A serializer for our message model."""

    class Meta:
        # Tell the serializer class that the data should match our
        # "Message" database model.
        model = models.Message
        # Tell it we only expect to see the 'message' field (as all other
        # fields will be automatically generated).
        fields = ('message',)

Now we will create our view. The view is responsible for receiving the users input, sending it to the serializer and displaying a meaningful output.

In the ‘api’ directory, edit the file to look like this:

from random import randint

from django.shortcuts import render
from django.db.models import Count

from rest_framework import views
from rest_framework.response import Response

from . import serializers, models

class MessageView(views.APIView):
    """View to managing messages through the API."""

    # The 'serializer' class takes out input and turns it into
    # a Python object we can play with.
    serializer_class = serializers.MessageSerializer

    # This is what happens when we receive a HTTP POST request to the API.
    def post(self, request, format=None):
        """Receive the post of the new message and return a random one."""

        # First, let's get a random message.
        # (We do this first to avoid getting the same message the users posts.)
        random_message = self._get_random_message()

        # Send the users input to the serializer class.
        serializer = self.serializer_class(
        # Check that the users input is valid. Raise an exception if it's not,
        # as DjangoRestFramework will automatically display the error to the
        # user.
        if serializer.is_valid(raise_exception=True):

        # If we got this far, no exception was raised and the input is valid.
        # So let's mark the "random_message" as read.
        random_message.is_read = True
        # Now save the updates to the 'random_message' in the database.

        # Now return the data of the serializer class.
        return Response(self.serializer_class(random_message).data)

    # This is our method that will get a random message.
    def _get_random_message(self):
        """Get a Random Message from the Database."""

        # Get the count of un-read random messages in the database.
        count = models.Message.objects.filter(

        # Get a random number between the count.
        random_index = randint(0, count - 1)
        # Select the unread message for the random number that was selected.
        random_message = models.Message.objects.filter(

        # Return the random_message.
        return random_message

Now that we have our view, we need to create a URL that points to it. In the ‘miab_backend’ directory, edit the file to look like this:

from django.conf.urls import url
from django.contrib import admin

from api import views

urlpatterns = [
    url(r'^api/message/$', views.MessageView.as_view()),

Finally, let’s test the API. The best thing about Django REST Framework is that it automatically gives you a working interface that you can immediately use in the browser.

Go to your browser, and navigate to http://<Server IP Address>:8000/api/message (So, in my example, the address would be The Django REST Framework interface should load. In the Message field, type a positive message and click Post.

Enter Message Screenshot

You should see one of the other messages returned as a response:

Create Message Response Screenshot

And that’s it! You now have the working REST API. Stay tuned for the next post which will make use of our API and turn it into a working App.


5 replies
  1. Jamie Russell
    Jamie Russell says:

    Really enjoying the read Mark and looking forward to part three. Work with a team of three front end developers who are complete novices when it comes to apps so the step by step guide is really helpful to us gaining an understanding in the process. Thanks again and keep up the good work.

    • mark
      mark says:

      Hi Jamie, thanks a lot for the comment, it means a lot. As you may have seen, the third part is online now. I hope you find it useful. I would love to hear about the results you get after following the guide!

  2. Mimish Hamish
    Mimish Hamish says:

    Hi Mark,
    This is awesome. I need to get I touch with you as I’m building an app using Django on Centos 6.7 Linux, on virtual of and I’m quite a newbie and are struggling in some configuration.

  3. sajjan jyothi
    sajjan jyothi says:

    Hello Mark,
    Nice tutorial. I am looking for a face to face tutorial for Django in London.Could you please help me in this.



Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

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