7401ICT: Django I: Introduction


Background

Introduction

Django is a free, open-source, widely available, practical, well-documented, labour-saving Python-based framework for Web application development.

It is used for implementing some of the Web's largest applications, including several online newspapers such as The Washington Post.

The latest official version of Django is 1.3 (March 2011). If you wish to install Django on your own computer, you can safely install either version 1.3 or the latest development version 1.4 pre-alpha (as installed on dwarf). (Note that Django does not run under Python 3.)

References

The three books listed above are all available in print and/or online through the University Library.

Projects

A Django project is a directory where all information about a single self-contained Web application is stored. To create a project, give the command:

$ django-admin startproject projectname

This creates a directory projectname containing, in particular, the files README.txt, manage.py, settings.py and urls.py. (These files may have slightly different contents on dwarf from the standard distribution.)

You can run a development server for this project with the commands

$ cd projectname
$ python manage.py runserver 0.0.0.0:80xx
where 80xx is a distinct port number between 8001 and 8049 inclusive. You can then access the (trivial) project just created by giving the following URL to your browser:
http://dwarf.ict.griffith.edu.au:80xx/
(Note the final slash.)

Normally, no stored data is associated with a Django project.

Apps

A Django app is a directory where information about one self-contained component of a Web application is stored. Normally, each app has associated stored data. The structure of the data associated with a Django app is defined by one or more models and the (server-side) code executed when HTTP requests to particular URLs are made is defined in one or more views (or controllers).

To create an app, inside a project directory, give the command:

$ python manage.py startapp appname

This command creates a directory appname containing, in particular, a file models.py (for defining the data used by the app) and a file views.py (for defining the Python methods, or views, called when HTTP requests to particular URLs are made). Other important files concerning URLs (urls.py), forms (forms.py) and admin (admin.py) are also stored in the app directory.

In general, there is a many-to-many relationship between projects and apps: one project may use several apps, and one app may be used in several projects. For this reason, it's important to try and keep the definition of each app independent of particular projects, if possible.

However, in this course, for simplicity, each app will be associated with a single project.

Project structure

The following is the structure of a typical Django project (for this course):

project
|___README.txt		project summary
|___manage.py		Django executable
|___django.db		SQLite 3 database
|___settings.py		configuration
|___urls.py		project URL configuration
|___app1		app directory
    |___admin.py	admin configuration
    |___forms.py	form definitions
    |___models.py	data model definition
    |___tests,py	test definitions
    |___urls.py		app URL configuration
    |___views.py	app view definitions (controller)
|___app2
    |___as above
|___other apps
|___media		uploaded (image) files
|___static		static style, HTML, image, script files
    |___css
    |___html
    |___img
    |___js
|___templates		template directory
    |___admin		admin template directory
    |___app1		app1 template directory
    |___app2		app2 template directory
    |___other apps		

Please refer back to this diagram when developing. Some of these files and directories are created automatically for you; some must be created manually by you. All files must be world readable (604). All directories must also be world executable (705). It's convenient if you also make file manage.py world readable and executable (705).

Variations are possible. For example, you can put template directories inside app directories. You can put static directories inside app directories. It depends

Note that this structure is designed for development. Changes may have to be made, particularly to the handling of static files, for deployment, but deployment of Django projects is outside the scope of this course.

Project summary: README.txt

The readme file of a project identifies the project and its author, summarises its purpose, describes how to use the project, and possibly summarises the implementation of the project. It is provided for the benefit of (other) developers (and examiners) who may need to maintain the project.

Settings: settings.py

The settings file of a project is where information is stored about the database used, the time zone used, the URLconfs used, the apps used, the templates used, the media files used, and so on. The initial settings.py file on dwarf is configured for our particular environment.

You need to extend INSTALLED_APPS and possible TEMPLATE_DIRS every time you add a new app to the project. Other changes are also sometimes required.

URLconfs: urls.py

A URL configuration file (aka a URLconf) defines the URL patterns used by a project (or app) and maps (or routes) each of these URL patterns to o Python method called a "view". This Python method (or view) is called whenever an HTTP request is made to a URL that matches that pattern. For example, if we want every URL of the form http://host/polls/ to be processed by a Python method index, and every URL of the form http://host/polls/12/ to be processed by a Python method detail with argument 12, then the URLconf would need to contain lines of the form:

url(r'^polls/$', index),
url(r'^polls/(?P<poll_id>\d+)/$', detail),
url(r'^polls/add/$', add, name='add'),

Here, "polls/\d+/" is a regular expression that matches any URL path of the form polls/digits/, where digits is a sequence of one or more digits, and poll_id is an identifier that is used in the view detail to store the particular digit sequence. The last, common pattern, for adding a new poll, is named; it's incredibly useful to give every pattern a name.

To keep each app independent, it's desirable to have a separate URLconf for each app. This requires the URLconf for a project that uses that app to contain a line of the form:

# App-specific URLS
url(r'^tag/', include('projectname.appname.urls')),

The mapping from each URL of the form /tag/anything/ to its corresponding view must then be defined in the URLconf urls.py of the app appname. (See the Django tutorial as a first example.)

Models

A model is basically a Python class definition, with extensions. Each such class definition is translated by Django into an equivalent SQL "create table" statement. It's important to note that the SQL table so created always has an automatically generated, non-null, integer, primary key called id. It's possible to specify a range of field types, foreign keys, and many-to-many relationships in such model definitions. Django can use this information for form input validation and query answering.

Each model belongs to a particular app.

After defining - or extending - a model, it can be translated into the corresponding relational table in your nominated database with the command

$ python manage.py syncdb

which performs the necessary object-relational mapping to create the tables in the database specified in the project's settings.py file.

The Django overview describes how to define models (tables), how to create and update model instances (rows), and how to query the sets of defined instances. The model definitions here require the following line before the definitions:

from django.db import models
Queries

Django provides an API to selectively retrieve data without having to use SQL (though you can if you absolutely need to).

The Django overview describes how to create and update objects, retrieve single objects or lists of objects, follow one-many links and perform implicit joins, all using an (in principle) simple object-oriented API.

Views

A view is a Python function that responds to an HTTP request for a particular URL and that normally returns an HTML document. Every view has request as its first argument. This argument may contain form data, described later.

A view may also contain additional arguments, e.g., the poll_id value used in the example above. The simplest way to return an HTML document is by using the function render, which takes the request, an HTML template and a context (a Python dictionary) as arguments, and returns the HTML document resulting from substituting the context into the template.

The most common views either query the database and then render an HTML template containing the results (using render) or update the database and then redirect to another URL (using redirect).

Each view belongs to a particular app.

Most view definition files require at least the following lines at the start:

from django.shortcuts import render, redirect, get_object_or_404
from django.core.urlresolvers import reverse

Templates

A template is a skeleton of an HTML document. It may refer to "variables" whose values are passed in through contexts. Django uses its own template language, but others may be used instead. The Django template language is easy to learn from examples.

Typically, each app will use several different templates. To ensure each template in the same app has the same structure, it's convenient to use a single "base template" and to derive each separate template from the base template.

Templates associated with an app are normally stored in a templates subdirectory of that app (though some examples used in this course store them in a templates/app subdirectory of the app's project).

Again, see the Django overview, which also gives simple examples of views and templates.

The (U)MVT pattern

This approach of designing Web applications by separating the models (data), views (code) and templates (presentation) is called the MVT pattern. It's equivalent to (but clearer than) the more familiar model-view-controller (MVC) pattern used in Java and in Ruby on Rails.

Because URLs are so important in this process, it is perhaps more precise to say that Django uses a UMVT pattern.

Thus, the most important tasks in the the design of a Web application using Django are the design of its URLconf files, its models, its views and its templates.

Forms

Form data is transferred in HTTP requests as a dictionary in the field request.GET or request.POST of the argument request. From this dictionary, one can obtain the value passed from the form, as the value for the key that equals the name of the corresponding form element, e.g., request.GET['quantity']. It's normally better to use the dictionary method get(), which allows a default value to be provided if no value is associated with that key, e.g., request.GET.get('quantity',0).

Later we shall study how to validate user-entered form data, but fortunately this is very easy.

We shall also study how to define forms, particularly forms based on a given model, a technique that significantly simplifies development.

Development

To summarise, to create a Django application, we must create a Django project and one or more Django apps.

In the project directory, we must edit the README.txt, settings.py, and urls.py files, and create templates, static, and possibly other directories. (The static directory contains static HTML files, JavaScript files, style sheets, images, and so on.)

In each app directory, we must edit the urls.py, models.py, views.py, and possibly tests.py files, and create admin.py, forms.py, and possibly other files. We normally also create a subdirectory of project/templates for that app.

The key to designing the application is to focus on the (U)MVT pattern: URLs, models, views, templates. The design of page transitions, as documented in a transition diagram, is also important.

Some common Django commands are:

$ django-admin.py help
$ django-admin.py startproject projectname

$ python manage.py help
$ python manage.py dbshell
$ python manage.py shell
$ python manage.py startapp appname
$ python manage.py validate
$ python manage.py syncdb
$ python manage.py runserver 0.0.0.0:80xx

The manage.py commands may also be given in the shorter form

$ ./manage.py args...

if the file manage.py is executable (705).

It's useful to run the commands validate and syncdb after each change to files settings.py and models.py to test that the changes are "correct".

Always remember to kill your development server before closing the terminal window it's running in.

Administration

Django provides very powerful facilites for administering users, groups, models (data), sites, and so on. To enable these, edit settings.py as indicated, give a username and password when you first do manage.py syncdb (always use the same simple username and password, I recommend admin and password during development), and give the following URL to your browser to access the administration interface.

http://dwarf.ict.griffith.edu.au:80xx/admin/

This works best if you have registered your models in file admin.py.

Static files

Django is primarily designed to serve dynamic documents. It's unnecessarily inefficient at serving static documents such as CSS files, JavaScript files, static HTML files, image files, video files, and so on. Such documents should be stored separately so they can be served efficiently in a production environment. For development, and in this course, it suffices to use the approach described above and in the Django documentation Managing static files. In brief, store static files in the project's static subdirectory, use the shortcut render() to render templates in views, and use {{ STATIC_URL }} in templates to refer to the static directory.

It's also important to study the examples provided.

Guestbook example

This is a first complete example to study.

It can be copied from ~s352978/pub/guestbook.zip on dwarf and expanded in your own Django directory. Use the following commands on dwarf:

$ cp ~s352978/pub/guestbook.zip .
$ unzip ~s352978/pub/guestbook.zip

To give the admin interface your username/password instead of my username/password, you need to delete the database file, and run the management command syncdb. You can save the data first and restore it afterwards using the management commands dumpdata and loaddata if you wish.

Important topics missing from this version of the guestbook example are searching, and pagination. These will be described later.

Polls example from the Django tutorial

To be demonstrated in lectures and completed as a laboratory exercise.