Building Your First Django Application
This tutorial is about web development. You’re going to learn how to develop a web application that could be easily used in the real world. You’ll see some of the many facilities that Django offers. To get the most out of this tutorial, you should know something about web development, Python and HTML/CSS.
Let’s get it started!
“Django is a high-level Python Web Framework that encourages rapid development and clean, pragmatic design.”
djangoproject.com
Suppose a local market of your town, the D-buy, knew that you’re a developer and hired you to develop an e-commerce website for some of their products. You, as a Python developer, took the job and started to develop your solution.
If you don’t have Django installed on your machine, you can install it via Pip. For this tutorial, we’re going to use Django 1.10 and Python 3.5.
Pip is a package management system used to install and manage software packages written in Python. It is a better alternative than installing your software through compiling the source code, downloading and install or installing from other package management system because it’s the default one. All Python packages keep their version on Pip updated.
Pip on Python 3.5 is already pre-installed. For OSX and Linux, Python is also already installed, and you can get more information on how to install on other operating systems here.
Once you have Python all set up, you can install Django. But first, we have to create a virtual environment. Virtualenv is a tool that creates isolated Python environments. Let’s say we have two different projects, one with Django 1.10 and another with Django 1.9. We don’t want to keep installing and uninstalling Django everytime we change context.
# Create the virtualenv $ python3 -m venv dbuy # activate it $ source dbuy/bin/activate # the $ pip install Django # to ensure django is installed $ django-admin --version # it will return the version of your django package
With django already installed, you can start our application.
$ django-admin.py startproject dbuy
As you can see, a folder named ‘dbuy’ was created on your directory. Get into it and see the files created.
$ ls dbuy $ cd dbuy $ tree . ├── dbuy │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py
1 directory, 5 files
These files are:
* manage.py – A file that lets you handle commands into your Django project.
* dbuy/__init__.py – An empty file that tells Python that it’s folder is a package.
* dbuy/settings.py – Contains your project settings.
* dbuy/urls.py – The url handler of the Django project.
* dbuy/wsgi.py – A file to serve WSGI-compatible webservers. (It won’t be part of our tutorial)
The development server
Django has its own development server where you can access it via a url and run whenever you want. Just run the following command:
$ python manage.py runserver
You should see the following output command line:
Performing system checks…
System check identified no issues (0 silenced).
You have 13 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run ‘python manage.py migrate’ to apply them.
December 02, 2016 – 10:24:06
Django version 1.10.4, using settings ‘dbuy.settings’
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
And, if you visit http://localhost:8000/ on your browser, you should see a Welcome screen.
This is the Django development server, a Web server written in Python. Note that this server is not meant to be used in running your applications for production, it’s meant to speed your development.
Initial setup
Open dbuy/settings.py. It’s a Python file that represents Django settings. You’ll see database, timezone, admins, static and template configs. At first we’re going to set up the database. The DATABASES variable is a python dictionary that stores Django database settings.
Listing 1. Python code.
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } }
You can set more than one database. But for this tutorial, we’re using the default one. The keys represent the settings of a database.
ENGINE – What database you’ll use. Django supports officially PostgreSQL, MySQL, Oracle
and SQLite3. We’re going to use SQLite3.
NAME – Your database name. In our case, the name of the file.
Take a look at INSTALLED_APPS setting. A tuple that shows all Django applications that are activated in your project. You can create your own pluggable apps, package and distribute them to others developers.
INSTALLED_APPS comes with some apps, already included in Django. You can install other apps, made by others or by yourself. Also, you can create your own pluggable apps, package, and distribute them to other developers.
Note that, when you ran the `runserver` command, it asks for migrations and creates the db.sqlite3 file. Now, let’s run those migrations.
$ python manage.py migrate
This command will identify all the INSTALLED_APPS and create all the necessary tables for your database.
Creating your apps
You’re developing an e-commerce, so what should you have? In your e-commerce, you’ll just have a list of products that can be grouped by categories and be bought by a customer. So, let’s start implementing the products. In your shell, type the following command:
$ python manage.py startapp products
A new directory has been created on your project folder.
. ├── db.sqlite3 ├── dbuy │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── products ├── admin.py ├── apps.py ├── __init__.py ├── migrations │ └── __init__.py ├── models.py ├── tests.py └── views.py
A Django app is a Python package with some files that follows some conventions. You can create the folder and the files by yourself but the ‘startapp’ command eases your life. The next step is to write your models to define your database. Our products will have name, description, price and categories. The categories can be implemented in two ways: as a field of the product or as another model. At first, we’re going to do as a field. Your products/models.py should look like this.
Listing 3. A longer piece of Python code
from django.db import models class Product(models.Model): CATEGORIES_CHOICES = ( ('eletronics', 'Eletronics'), ('clothes', 'Glothes'), ('games', 'Games'), ('music', 'Music'), ) name = models.CharField(max_length=200) description = models.TextField() category = models.CharField(max_length=30, choices=CATEGORIES_CHOICES) price = models.DecimalField(decimal_places=2, max_digits=6)
In Django, a model is represented by a class that inherits from django.db.models.Model. The class variables represent the fields of the table created by the ORM. Each field is represented by an instance of a Field class. By default, all these fields are required. If you want to set an optional field, you should explicitly say this, by using the parameters blank and null.
Some fields, like DateTimeField, blank (not required) must be null. Therefore, if you set as blank and don’t submit the value of the field, it will raise IntegrityError because blank is allowed but null is not. You should avoid using null=True on string based fields because doing that will allow two possible fields for “no data”: Null and the empty string.
Some fields have required arguments, e.g. max_length in CharField and the max_digits to the DecimalField. We’ll talk about it later. As you can see, we used the parameter choices on the categories. The choices parameter (optional) must receive an iterable object, of iterables of exactly 2 items (e.g. [(A,B), (C,D)])). The first one is the value that will be stored in the database and the second one is meant for humans.
What you just wrote gives you a lot of information. With the ORM, this class describes your database table and gives you access to it, but you need to activate it before. In dbuy/settings.py, add your app to the INSTALLED_APPS tuple:
Listing 4. A longer piece of Python Code
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'products', ]
And then, run the syncdb command.
$ python manage.py makemigrations $ python manage.py migrate
You’ll see that your product table was created. Now, let’s play a little bit with the database.
We’re going to use Python shell through the manage.py, that way, the Django environment is autoloaded on your shell.
$ python manage.py shell >>> from products.models import Product >>> Product.objects.all() <QuerySet []> # No product was created. >>> p = Product(name=”Pacman”, description=”some description”, price=12.99, category=”games”) # just created your product >>> p.save() # Now it is on the database >>> p.id 1 >>> Product.objects.all() <QuerySet [<Product: Product object>]>
But this representation isn’t the best. You can set your models in another way to represent your products as shown below:
class Product(models.Model): ... def __str__(self): return self.name
That way, you can see better your object.
>>> Product.objects.all() <QuerySet [<Product: Pacman>]>
Let’s deal with these objects in a better way than the command line. Django already comes with an admin interface that will ease most parts of your development. If you see dbuy/urls.py, you’ll notice that we have an admin path.
Listing of python code
from django.conf.urls import url from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), ]
Note that django.contrib.admin is already in your INSTALLED_APPS. Run the server, access localhost:8000/admin and let’s see the outcome.

To access the system, we need to create a superuser.
$ python manage.py createsuperuser
After creating a user, you can login into your admin interface.

There is an admin.py file in your products app. Import the Product model and register it.
from django.contrib import admin from products.models import Product admin.site.register(Product)
Now, you’ll be able to edit your products. The Django admin is a powerful tool and you can personalize it, read how to customize the admin to your needs here: https://docs.djangoproject.com/en/1.10/ref/contrib/admin/
We’re ready to publish something in our home page, at least a list of our products.
Writing your first views
A Django view it’s a callable (an object that can be called), that receives a request and returns a response.
Open your dbuy/products/views.py and write the following code:
from django.http import HttpResponse def index(request): return HttpResponse(“Welcome to D-Buy Store!”)
You just created the index view which receives a HTTP request and returns a response. However, by itself it does nothing, you have to set the urls to ‘find’ the view. On your dbuy/urls.py, add the following code:
from products import views url(r'^$', views.index, name="index"),
Now, you just need to visit the application on your browser to see if Hello World there. In the URLs, the first parameter is a regex that represents the actual url. The second one is the path to the view which will be called, and the third one is an alias that we’ll use later.
Do you want to see a list of the products? Then, you should start to work within the context. The context is a dictionary mapping template variable names to Python objects. Now, your view should look like this:
Listing 5. A longer piece of Python Code
from django.http import HttpResponse from django.template import RequestContext, loader from products.models import Product def index(request): products = Product.objects.all() template = loader.get_template(‘index.html’) context = RequestContext(request, {‘products’: products,}) return HttpResponse(template.render(context))
This will list all your products and render the template. When the render function finds a template variable ‘products’, it will associate with the Python variable. Now, you have to write your templates.
On settings.py, find the variable TEMPLATES and add the path to your template dir to the DIRS variable. It’s highly recommended that you don’t hardcode it. Most of the time you’re working, you read someone else’s code. So, you need a dynamic configuration for any operating system.
Listing 6. A longer piece of Python code
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
That way, you ensure that the path is always going to be right for any OS and in any path. Consequently, in the same folder of your settings.py, create a folder named ‘templates’ and create a file ‘index.html’, and start writing your first HTML page.
Listing 7. A longer piece of HTML code
<html> <head> <title> D-Buy </title> </head> <body> <h1> Welcome to D-Buy Store! Our products are: </h1> {% for product in products %} <h3>{{ product.name }}</h3> <ul> <li>{{ product.description }}</li> <li>{{ product.category }}</li> </ul> {% endfor %} <p> For more information please send an e-mail to [email protected] </p> </body> </html>
Now, run your server and access the url http://localhost:8000/
You should see something like this:

Ok, nice! But let’s use another function to return an HttpResponse object. Refactoring our view:
Listing 8. A longer piece of Python code
from django.shortcuts import render from products.models import Product def index(request): products = Product.objects.all() return render(request, 'index.html', {‘products’: products})
Better! The render function does the same thing to those lines of code, it receives an HttpRequest, renders the template with the context variables and returns an HttpResponse.
For now, you delivered a simple page that shows all the products of your customer. In the next part of the tutorial, you’re going to learn how to deal with media and static files and use some of the power inside Django.
If your client wants a page for each product, showing name, description, category etc., you’ll first create a url and view to get the specific product.
url(r'^product/(?P<product_id>\d+)$', 'products.views.product', name="product"),
A url is a regular expression. That way, you can specify the type of your url parameters easily. If you don’t know regular expression, you should read the python documentation [1] about it. All you need to know here is that, the url has this pattern /product/product_id, where product_id is an integer and the name of the view parameter.
def product(request, product_id): product = Product.objects.get(id=product_id) return render(request, 'product.html', {'product': product})
The view product received the product_id, made a query to the database and rendered the template with the product variable in the context.
Now here is the html code:
Listing 9. A longer piece of HTML code.
<html> <head> <title> D-Buy </title> </head> <body> <h1> {{ product.name }} </h1> <ul> <li>{{ product.description }}</li> <li>{{ product.category }}</li> </ul> <p> For more information please send an e-mail to [email protected] </p> </body> </html>
Run the server and access the url http://localhost:8000/product/1 and you’ll see something like that.
Just a small adjustment on the index.
Listing 10. A longer piece of HTML code.
{% for product in products %} <h3><a href="/product/{{ product.id }}">{{ product.name }}</a></h3> <ul> <li>{{ product.description }}</li> <li>{{ product.category }}</li> </ul> {% endfor %}
Or you can use the url template tag and the url name.
{% for product in products %} <h3><a href="{% url 'product' product.id %}">{{ product.name }}</a></h3> <ul> <li>{{ product.description }}</li> <li>{{ product.category }}</li> </ul> {% endfor %}
This is a quick start for Django. So far, we’ve covered views, models and templates. If you need some help, don’t be afraid to send me a message through my twitter handle: @_renatooliveira.
Thanks!
About the author
Renato Oliveira is co-founder at Labcodes, a Brazilian software development studio that delivers great products. Django Software Foundation Fellow and organizer of conferences in Brazil. Contact the author: @_renatooliveira.
References:
[1] – Regex https://docs.python.org/3/howto/regex.html
