Getting Setup and Started

First, open up a terminal window and change directory to a suitable location - i.e. your home directory where you write code. Let’s assume it is called: /absolute/path/to/code

Testing if you have Django installed

make sure that you have Django installed by issuing the following command:

python -c "import django; print(django.get_version())"

Hopefully, you will have Django 1.4 installed, otherwise go to https://docs.djangoproject.com/en/dev/topics/install/

Creating a Django Project

Django provides a lot of machinery and infrastructure for you. To get started you will need to first create a Django project. Within this project you will create apps for your site.

django-admin.py startproject tango_with_django_project

If this fails to run, you might need to make sure django-admin.py is on your path, or that it is executable, or that you have permission to run this script (i.e. you may need to use sudo).

All going well, a directory called tango_with_django_project should be created in your current directory. Within this directory you should have:

  • a Python script called manage.py,
  • and another directory called tango_with_django_project.

The manage.py script is pretty important and you will be using this a lot. Try running the command python manage.py runserver. You should see:

Validating models...

0 errors found
Django version 1.4, using settings 'tango_with_django_project.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Now open your favourite web browser and visit: http://127.0.0.1:8000/ . You should see a welcoming Django message indicating that your project is setup. The page is being dispatched by Django’s lightweight development web server (which is great for testing, but should not be used for production).

Note that you can specify the port (i.e. 1234) or the IP address and port of this webserver by running either of the following commands:

python manage.py runserver 1234

python manage.py runserver 0.0.0.0:1234

0.0.0.0 should be replaced with the IP address of your machine. This is useful when you want to demonstrate your project across an internal network; as it allows other machines to connect to the django webserver running on your machine and access the application running (assuming there is no firewall blocking incoming connections on the port that you have chosen).

Creating a Django Application

Django Projects are essentially a collection of configuration and applications for a particular web site. A project can contain multiple applications, and thus a website is composed of a number of applications.

An application does something (if that is not obvious), like a doodle poll, a blog, a poll, etc. So to make your project do something you need to create an application which will dispatch content via the web server, to do this run:

python manage.py startapp rango

This will create a directory within tango_with_django_project called rango and it will contain the following files:

__init__.py
models.py
tests.py
views.py

views.py and models.py provide two of the main files that you will be interacting with. They are form part of the main architectural design pattern employed by Django, namely, Model-View-Template.

In views.py, you will need to add/create methods that take requests and return responses (usually XHTML/HTML/XML responses, but they could be JSON or some other format).

In models.py, you will need to specify the entities and relationships of your data models as django.db.models.Model classes. Django provides the machinery to transform these classes into SQL and handles the object relation mapping, which is really convenient!

See https://docs.djangoproject.com/en/1.4/intro/overview/ for more details about how the Model View and Templates relate to each other.

But before you create Models, Views and Templates, you should add rango to the INSTALLED_APPS tuple in the settings.py file.

INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
# Uncomment the next line to enable the admin:
# 'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
'rango',
)

Creating a View

Let’s set up a simple view (without using models or templates).

Open rango/views.py and add the following Python code:

from django.http import HttpResponse

def index(request):
        return HttpResponse("Rango says: Hello World!")

This is a pretty simple view. Now, that you have created a view, you need to do a bit of plumbing, and map a url to the view called index.

Mapping the URL

In the rango directory create a file called urls.py, in this file add the following lines of code:

from django.conf.urls import patterns, url

from rango import views

urlpatterns = patterns('',
        url(r'^$', views.index, name='index')
)

This imports the necessary Django machinery (patterns and url) along with access to the methods in views (in this case the index method we just created). The urlpatterns stores the mappings of urls to methods. Here the regular expression ‘^$’ means that if we match an empty path after the url, then Django will invoke the views.index method.

However, because Django will dispatch anything, we also need to set up urlpatterns for our project. This will connect up the project urlpatterns to the application urlpatterns.

To do this, go to the directory tango_with_django_project and open up the existing urls.py file. It already has urlpatterns defined, but you need to add in a url pattern that will direct requests to the rango application, so your urlpatterns will be:

urlpatterns = patterns('',
        url(r'^rango/', include('rango.urls')),
        )

Now, project is connected with the application, and the application is connected to the view, if you visit: http://127.0.0.1:8000/rango [1] you should see “rango says: Hello World!”.

It is not much to look and doesn’t do very much but this example shows how the connection between the project and application operate. Now, the reason why you need to connect both project to application, and application to view, is to decouple the application from the project. This makes it easier to move applications into new projects i.e. an application can be in multiple projects. For instance, a polling widget could be put within multiple sites.

To walk through the process of what is happening, first, the Django web server receives a request, http://127.0.0.1:8000/rango, second, the web server strips back the request to: rango.

It then looks through the url patterns in the tango_with_django_project/urls.py and if one of the regular expressions in urlpatterns matches “rango” it then passes the request onto the python module rango.urls to handle. In this case, Django removes rango from the request and passes on an empty string “” to rango.urls in rango/urls.py and examines the urlpatterns. It finds that the regular expression r’^$’ matches the empty string “”, and invokes the index request method (rango.index).

Having a good understanding of the mechanics behind Django is important so check out https://docs.djangoproject.com/en/dev/topics/http/urls/ for more details to get familiar with the working with URLs in Django.

Essentially, within an application you will be creating a number of views and url mappings. More complicated url mappings that include parameterization can also be handled (see https://docs.djangoproject.com/en/dev/topics/http/urls/ for more details). Making readable and clear url mappings is an important aspect of designing a web application. Later in this tutorial dynamic views will be created where different ways to create such mappings are discussed

Adding a Template

Okay. So far you have plugged a few things together to create a simple HTML page. Since there is a lot of repeated structure/layout for HTML pages within a website (i.e headers, footers, sidebars, etc.) Django provides Templates as a solution. In this first example you are going to create a static template, to dispatch a static html page. Later in this tutorial Templates will be used in conjunction with Models to dispatch dynamic data.

First, create a templates directory in your project directory called templates, then create another directory called rango within templates.

Next open up the settings.py in tango_with_django_project. This settings file provides the configuration data for your application. Scroll down to TEMPLATE_DIRS and add in the path to your templates directory. So for me it is:

TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
        '/absolute/path/to/code/tango_with_django_project/templates',
        )

Now in your template/rango directory create a file called index.html, and in that file put:

<HTML>
<HEADER><TITLE>rango</TITLE></HEADER>
<BODY>
rango says: Hello World!
</BODY>
</HTML>

Now, you need to modify the index view so that Django dispatches the index.html template. To do this, add in the following import:

from django.template import RequestContext, loader

and change the index method to:

def index(request):
        # select the appropriate template to use
        template = loader.get_template('rango/index.html')
        # create and define the context. We don't have any context at the moment
        # but later on we will be putting data in the context which the template engine
        # will use when it renders the template into a page.
        context = RequestContext(request, {})
        # render the template using the provided context and return as http response.
        return HttpResponse(template.render(context))

Note that the context is essentially just a dictionary mapping template variable names to Python objects.

Run the web server and reload the page. All going well you will see the html page. If not, and you get an error, check that you have spelt everything correctly, and that the template that is it trying to load has the correct path.

For your rango application, you can now add other templates to templates/rango and use them in our view methods. The Django Template Engine is pretty powerful and provides lots of functionality (including inheritance and ways to process and access variables in the provided context - see https://docs.djangoproject.com/en/dev/ref/templates/ for more details). You will touch upon some of this functionality as you progress through the tutorial.

Setting up Static Files

Admittedly, our rango site isn’t looking too fancy. So it would be nice to be able to include other types of media in our rango (i.e. images) and also be able to include CSS and JAVASCRIPT within our rango.

To do this, create a directory in the project called static, and within here created another directory called imgs. Now place a jpg in the imgs directory, lets call it leifos.jpg. To point Django to these static files, we need update the settings.py for our project and update the STATIC_URL and STATICFILES_DIRS settings:

STATIC_URL = '/static/'

STATICFILES_DIRS = (
'/absolute/path/to/code/tango_with_django_project/static',
)

This is the simplest way to serve static files during development (though it is not appropriate for production). To access the files through the webserver you can visit http://127.0.0.1:8000/static/imgs/leifos.jpg

Accessing Static Files in the Template

To reference the static files from the template you can update your index.html template as follows:

<BODY>

        rango says: Hello World!
        <IMG SRC="{{ STATIC_URL }}imgs/leifos.jpg" />

</BODY>

You’ll notice that in the template you have put a template variable {{ STATIC_URL }}, the value for this, which is ‘/static/’, comes from the context that you requested in the view.

You can also put css and javascript in the static files directory and access it via the STATIC_URL.

See https://docs.djangoproject.com/en/1.4/howto/static-files/#staticfiles-in-templates for more details on how to refer to static files in templates.

Setting up Media Files

You may also want to setup a development media server as well. This is helpful for debugging (but is not advises for deployment) as it enables users to upload imgs, videos, and other files to your site. For instance when a user registers with the site they can upload a picture.

To set up a development Media Server edit the projects tango_with_django_project/urls.py and add in the following imports and the if statement after the urlpatterns:

from tango_with_django_project.settings import DEBUG
from tango_with_django_project.settings import MEDIA_ROOT

if DEBUG:
urlpatterns += patterns('django.views.static', (r'media/(?P<path>.*)', 'serve', {'document_root': MEDIA_ROOT}), )

Now in settings.py you will need to set the path of MEDIA_ROOT, which will be where the media files are stored. Also set the MEDIA_URL =’/media/’. You will be able to access the media stored in MEDIA_ROOT via the MEDIA_URL in your templates.

Caution

Setting up the site media and static files this way is designed only for development, and not for production. The Django documentation warns that it is probably grossly inefficient and insecure (see https://docs.djangoproject.com/en/1.4/ref/contrib/staticfiles/#static-file-development-view).

Exercises

  • Add another image to your index page
  • Add a video to the index page
  • Add an about page which contains some text about the project team (with a picture of the team)
  • Add a link from the index page to the about page
  • The tutorial uses absolute paths i.e. in settings.py, for example, STATIC_PATH = ‘/Users/leifos/code/static’ - this is not a very good idea. Why?
  • Use python’s os module (import os) and get the current working directory with os.getcwd(). Update your settings.py module so that the application can be run on different machines without having to change the paths. This is handy for development purposes, however, when deploying your application it is likely that you will need to put in absolute paths.

Footnotes

[1]Assuming that you are using the IP address: 127.0.0.1 and port 8000 when running your web server.