The Django framework: An introduction

General news, Tutorials

The Django framework: An introduction

In this Django tutorial, Production Director, Thomas Rumbold, walks us through the basics of the Django Framework and Technical Director, Daniel Samuels, shows us how to get started writing our first lines of code.

 

What is a web framework?

A web framework (or web application framework) is a software framework that is designed to support the development of web sites and online software applications - including web services, web resources and web APIs. Web frameworks aim to alleviate the overhead associated with common activities performed in web development by providing a series of tools designed to simplify and accelerate the technical development process for web developers.

So, what is Django, and what is it good for?

Simply put, Django is a Python web framework designed to enable website and web application developers to build and deliver complex projects quickly, securely, and to a consistent, ‘clean’ style. It’s got a series of out-of-the-box tools that support, enhance and speed up the traditional web development process, and help get otherwise complicated work done rapidly to a very high standard.

Django provides a series of software tools that take care of a lot of the non-project specific ‘grunt work’ for a developer straight out of the box. That means that developers can spend more of their time writing the important stuff - like actual features - while lots of the mundane, ‘standard’ stuff that needs to happen in the background to serve a web application is handled automatically.

Have I heard of anything that’s built on Django?

Yes, you probably have. Pinterest is a very high traffic, distributed Django system. Instagram’s web application is written on Django. The Washington Post, Rdio, The Onion and NASA also use Django. You’re probably sensing a theme here. These guys are in charge of complicated, very high-traffic, large scale systems - and they’re all doing it pretty well (or appear to be, anyway!). Bitbucket and EventBrite also run on Django (and in fact, the current EventBrite team are made up of a number of Django’s core development team).

So, what does it look like on the technical side?

There’s an awful lot to Django - lots of pretty brilliant engineering under the hood, and subsequently lots of great features to use. Covering everything Django can do would be impossible for a single blog (and that’s what the documentation is for) - but if you’re interested in a more general technical evaluation of how it works, you’ve generally got the following five main components.

Apps

Building features in Django typically means you’ve got to put together an ‘app’, which is designed to do a single thing, and do it very well. An app in Django is a self-containing code structure that is made up of a number of different files that usually contains everything it needs to get something done - as well as any references to other apps, if you need to share data between them.

An ‘app’ is made of a series of base files. You can also create new ones and import them where you think they’re necessary - but for building simple applications, the base project structure is ample.

Models

Models in Django are a mechanism to allow developers to interact with a database (doing things like creating, reading, updating and deleting) without directly touching the database layer of the stack with any of their own code. Models are what are referred to in the software world as an ‘abstraction layer’ between the database and application layer - and in Django’s specific implementation, it means you almost never have to write any raw SQL - because your model is a fully accessible Python representation of your database table. That means that instead of writing a raw query, you can simply import and call elements from your model in Python, without having to go any lower down than the application layer.

It’s a brilliant way to keep code clean, well structured and reusable - and of limiting any interactions that could potentially be dangerous or inconsistent. It also means that a lot of the SQL specific stuff (like validation) can be kept and handled at the model level, which makes it very easy to scan a model file and understand how it corresponds to the tables in your database, thanks to Django’s heavy lifting behind the scenes.

Views

After creating a model, creating your database and then storing some data, you’re probably going to want to do something with it. Serving data out to a HTML template for the user to see requires what is called a ‘View’ - which is a file designed to process and deliver data to other parts of the web application. Views are powerful because they’re just Python files - anything you can do in Python you can do within a view - which means you can access, cut up and stitch together data in pretty much any way you like. Django has a whole load of tools to help developers do it rapidly, too.

Importantly, Django's Generic Class Based Views are a powerful time saver designed to stop you rewriting the same views over and over again for different projects.

URLs

Good URL schemas underpin any good web information architecture, and Django is designed to help build simple, dynamic URL systems with ease.

Each app usually has an associated urls.py file - designed to allow you to define a collection of routes which Django will test the website visitor's current URL against. If there's a match, then Django will call that URL's associated view and execute any logic associated with it, returning the result to the appropriate template, and the user to the appropriate URL. This in-built URL handling system is an exceptionally powerful way to architect large, dynamic URL schemas, with very little overhead.

Templates

Templates are the parts of a website or web application that are served as either individual HTML pages, or components of other HTML pages to website visitors. They’re written in HTML, and their styling is dictated by CSS - but Django’s own templating language means that you can call database objects out with ease. They can either be fed data from a corresponding view file - or they can feed data to a view, by way of taking input via a form.

Django’s templating syntax is simple and effective - but a good rule of thumb is to keep as much ‘logic’ away from templates as you can, to keep the code clean and understandable. Any complex processing or filtering should be done either at the model or view level (or potentially, in a template tag) - so when it lands in your actual template, the processing is already done and the front end work is as simple as it can be.

Django has a lot of cool, built-in filtering tools that help you get work done with your data. Worth taking a look at!

Administration system

Django’s automatic administration system is hugely useful - mostly because of the amount of time it saves. It works like this - any app that you construct has it’s own corresponding admin file. Importing the relevant database models into that file, and then dictating how you want those fields laid out visually is all you need to do to create an administration system - because Django will take those components and make them accessible for an administrator (by default, at the /admin URL).

The beauty of this is that unless you want some advanced, custom features, there’s really nothing you need to do. You create some very small admin files and lo and behold - an administration system. How long would that have taken to write on your own?

So, how do I get started with Django? 

The Django community is a very active community of highly capable developers, and there are a lot of resources available to get started with. 

To demonstrate the simplicity of Django, we’re going to make a simple blogging app. (The final source code is available here: https://github.com/danielsamuels/gcbv-article/ )

To begin, you’ll need to have Python installed, it comes pre-installed on OS X and Linux based systems, so if you’re using either of those, you should already be set.  If you’re on Windows you’ll need to go to the Python website to download and install it. Before we install Django, we’re going to create something called a ‘virtual environment’. A virtual environment allows us to isolate the dependencies of a project from the rest of your system so you don’t end up with multiple versions of the same library trying to be loaded at the same time. To start using a virtual environment under Python 2 you’ll need to first install the package: pip install virtualenv. If you’re using Python 3, it comes with a virtual environment system built-in, so we’ll make use of that.

To create the virtual environment on Python 2 run `virtualenv .venv`, to create one on Python 3 use `python3 -m venv .venv`. Once the environment has been created it needs to be activated before it can be used.  You can do this by running `. .venv/bin/activate`.

Now we’re all set and ready to install Django without it affecting anything else - simply run `pip install Django`. The latest version will be downloaded and installed. To start using Django we’ll first need to create a project, Django provides a base template, so we’ll make use of that. Run `django-admin startproject blog .` If you view this directory you’ll see that a few new files have been created, these will form the basis of our project. 

This is the default project structure for a Django project, it’s the template that Django itself provides for you to use. It’s a great starting point.

What do each of these files do?

There are 4 files which are generated when you run startproject, they are manage.py, settings.py, urls.py and wsgi.py.  

The manage.py file is a replacement for the django-admin command we used earlier, it’s your main entry point into your application and it’s what we use to run any management commands related to our project, for example creating an admin user.  It’s very rare that you’ll need to edit this file.  

The settings.py file contains all of the settings for our project, such as the name of the project, the URL it will live under and so on.  We won’t be editing it as part of this process, but it’s worth having a look through it to see what’s in there.

The urls.py the base routing file for all requests which come into Django, it handles mapping the various URLs to their counterpart views. We’ll be editing this later on.
The wsgi.py file is used when you deploy your project to a server. It allows a WSGI HTTP server such as Gunicorn to mount your application and pass HTTP requests through.

Building it out

Now that we have the first files for our project, we’ll start building it out. To keep our workspace clean we’re going to create our application files within a folder in our project, rather than alongside everything else, so go ahead and create a folder called ‘blog’. You’ll also need to create an empty file named __init__.py in this folder so that Python knows it’s a loadable module. Once we have this folder we’ll need to create a “models.py” file inside it which will contain our representation of a blog post.  We’ll keep it simple and only include the title and content for now.  

from django.db import models

class Post(models.Model):
    title = models.CharField(
        max_length=100,
    )

    content = models.TextField()

Then we’ll need the individual “views” which take care of receiving the request, working out what needs to be done and then returning a web page. For this we’ll make use of Django’s “Generic Class Based Views” which provide a simple way to perform common tasks. Create a views.py in your blog folder with these contents:


from django.core.urlresolvers import reverse
from django.views.generic import CreateView, DeleteView, DetailView, ListView, UpdateView

from .models import Post


class PostListing(ListView):
    model = Post


class PostCreate(CreateView):
    model = Post
    success_url = '/'
    fields = ['title', 'content']


class PostDetail(DetailView):
    model = Post


class PostUpdate(UpdateView):
    model = Post
    fields = ['title', 'content']

    def get_success_url(self):
        return reverse('blog:detail', kwargs={
            'pk': self.object.pk,
        })

class PostDelete(DeleteView):
    model = Post
    success_url = '/'

The last file we’ll need in our app folder is urls.py. This will map the URL you visit in your browser to the relevant view in the views.py file. We’re going to use some regular expressions to match values within the URL, all they’re going to do is look for a number and pass it into the view as a ‘pk’ value - primary key - which will be used to find the blog post in the database.

from django.conf.urls import url
from .views import PostCreate, PostDelete, PostDetail, PostListing, PostUpdate


urlpatterns = [
    url(r'^$', PostListing.as_view(), name='listing'),
    url(r'^create/$', PostCreate.as_view(), name='create'),
    url(r'^(?P<pk>\d+)/$', PostDetail.as_view(), name='detail'),
    url(r'^(?P<pk>\d+)/update/$', PostUpdate.as_view(), name='update'),
    url(r'^(?P<pk>\d+)/delete/$', PostDelete.as_view(), name='delete'),
]

There’s a few small things we’ll need to do before our app is integrated into our project. First we need to add the app to the list of installed apps in the settings. So open up settings.py and have a look for INSTALLED_APPS. Add another line with the value ‘blog.blog’ (blog being the name of the project folder and also the name of the app folder). The last thing we’ll need to do is add the blog URLs to the project URLs. Open up the urls.py in the root of your project and add this line underneath the admin line:

url(r'^', include(‘blog.blog.urls', namespace="blog"))

You’ll also need to add `include` to the list of imports from django.conf.urls.

from django.conf.urls import include, url

We now need to let Django know about our new article model so that it knows it needs to create a database table. Go back to your terminal and run python manage.py makemigrations blog. You’ll see it create a file. Then run `python manage.py migrate`, it will turn all of the models in your project into database tables. You should now have everything in place to be able to run the development server, so run `python manage.py runserver`. You’ll see the server start up and direct you towards http://127.0.0.1:8000, which you can then visit.  

Django comes with a built-in server to use when developing your application.  It makes it very easy to get your projects up-and-running.

You’re going to receive an error saying a template is missing and this is a good thing - it means you’re hitting the correct view (in this case, it’s the PostListing view).

The next thing we’ll do is add all of the templates that we’ll need. We’ll need 4 templates in total: the blog listing, the article detail, the forms and the delete confirmation. We’re going to keep them as simple as possible for now, so go ahead and create these files:

templates/blog/post_confirm_delete.html

<form action="" method="post">
    {% csrf_token %}
    <input type="submit">
</form>

templates/blog/post_detail.html

<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>

templates/blog/post_form.html

<form action="" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit">
</form>

templates/blog/post_list.html

<ul>
{% for post in post_list %}
    <li><a href='{% url "blog:detail" post.pk %}'>{{ post.title }}</a></li>
{% endfor %}
</ul>

Your final structure should look like this:

__init__.py
models.py
urls.py
views.py
templates/blog/post_confirm_delete.html
templates/blog/post_detail.html
templates/blog/post_form.html
templates/blog/post_list.html

If you refresh your browser you should see your working site (note: you may need to restart the development server first). And there you have it, your very first Django-powered blog!

Quick tips
    •    If you’re going to be working on multiple Python / Django projects, it’s useful to make use of virtual environments to isolate your dependencies. You can run `pip install virtualenv`, `virtualenv .venv`, `. .venv/bin/activate` to start.

    •    Python comes with a useful program for installing dependencies, it’s called ‘pip’.  You can install Django by running `pip install Django`. If you want to share your requirements you can run `pip freeze > requirements.txt` and someone else can run `pip install -r requirements.txt` to install them.

    •    Django projects work best when they’re split up into manageable chunks, so consider splitting different parts of your project into their own apps, then split the individual components of the app into their own file. You’ll find it becomes much easier to maintain.


Django comes with a built-in server to use when developing your application. It makes it very easy to get your projects up-and-running.

When you run the development server the first time and navigate to http://127.0.0.1:8000, this is the page you’ll be greeted with. 

This is the default project structure for a Django project, it’s the template that Django itself provides for you to use. It’s a great starting point.

Abstracting away complexity

The example code demonstrates how easy Django makes it to develop applications.  With less than 30 lines of view code, you’re able to take care of listing news articles, creating new articles, viewing them, updating them and deleting them.  This is made possible to the amount of time spent by the Django developers in creating a collection of generic views which are both useful, but also unopinionated.  They deliver all of the functionality you require without getting in your way - and if you don’t like the way they’re doing something, you can just override or extend them with your methods. This level of thinking extends across the entire spectrum of Django features, with simplicity and security being the default.  Knowing that the framework is doing all of the heavy-lifting leaves you to take care of the application logic, making you more productive and able to deliver projects in a more timely manner.

Hopefully you're now up and running! We hope you enjoyed this introduction to Django - we'd love to hear your comments, and any suggestions for our next tutorial - leave them below.

Check here for more Django and Python tutorials for beginners:

Getting started with Generic Class Based Views in Django

An introduction to Python

(This article originally appeared in Linux Format Magazine.)