Note: This guide assumes that you have Python installed on your machine - if you don’t, head to python.org/download/ and download and install Python for your Operating System

Step One: Install Django

1. Install Pip

Pip is currently the most popular package manager for Python and helps you to manage the packages you require for you app (particularly useful is the freeze command - see Note 1).

You can install Pip with the instructions found at:

http://www.pip-installer.org/en/latest/installing.html

2. Install Virtualenv

Virtualenv sets up a Virtual Environment by creating a directory that contains packages that will only be accessible from the Virtual Environment. This means that other projects that you are working on won’t be affected if you install a conflicting package. Everything installed within the Virtual Environment is only accessed if it is currently activated.

To install Virtualenv, run the following:

$ pip install virtualenv

3. Set up Virtual Environment

You can set up a Virtual Environment by simply running virtualenv <environment name>, then activate it by sourcing the bin/activate file in the Virtual Environment’s directory:

Create Virtual Environment

$ virtualenv env_django_quickstart

Activate Virtual Environment

$ source env_django_quickstart/bin/activate

Deactivate Virtual Environment

$ deactivate

After running either of the first two commands you should see the name of the Virtual Environment in brackets in your command line: (env_django_quickstart)$

4. Install Django:

Ensuring that the virtualenv is activated, install Django with pip.

$ source env_django_quickstart/bin/activate
(env_django_quickstart)$ pip install django
(env_django_quickstart)$ pip freeze
...
Django==x.x.x
...

5. Start a Django Project

Run startproject to create a blank Django project in the current directory.

$ django-admin.py startproject django_quickstart
$ cd django_quickstart
$ python manage.py runserver
...
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

You should then see a basic welcome page for Django at http://localhost:8000/

Step Two: Setup a URL and View

1. Write the URLs

Open the urls.py file inside the django_quickstart directory and add the following url:

urlpatterns = patterns(
'',
...
url(r"^$", "django_quickstart.views.home", name="home"),
...
)

URL Pattern Breakdown:

  • url() contains your url pattern
  • r"^$" regular expression to match urls to
  • "django_quickstart.views.home" view to display for matched pattern
  • name="home" name given to pattern to allow it to be called inside code, such as links

The pattern here defines a regex with nothing between the line start ^ and end $ of the url and maps requests to this url to the ‘home’ view inside of the views.py file in the ‘django_quickstart’ directory.

The name=”home” simply allows the view to be referenced in other code as home (this can be namespaced to avoid clashing with another urls.py file defining the same name, eg ‘users:home’). An example of this would be in reversing urls to use in links:

<a href="{% url 'home' %}">Home</a>
<a href="{% url 'users:home' %}">Home</a>
NOTE: Namespacing of urls, like users in this case, requires that the users urls.py has been 'included' with a namespace of 'users' - click here for more information

3. Create a View

In the case of the example url pattern with a view declaration of "django_quickstart.views.home", the views.py file would be found/created in the ‘django_quickstart’ directory and the view would be called ‘home’ as in the following example:

from django.http import HttpResponse
def home(request):
return HttpResponse("We have a home view!")

Class Based Views

It is important to note that class based views (where views are declared as classes instead of functions) are declared in a different way to function based views. Class based views are declared in url patterns as follows:

from django_quickstart.views import Home
urlpatterns = patterns(
'',
url(r"^$", Home.as_view(), name="home"),
)

Please note that the view declaration does not have quotes around it as it calling the ‘as_view’ method from the class.

Please also note that in this example I have first imported the class based view called ‘Home’ from the views.py file in the ‘django_quickstart’ app.

The class based equivalent of the home view would then look like this:

from django.http import HttpResponse
from django.views.generic.base import View


class Home(View):
def get(self, request):
return HttpResponse('We have a new home!')

Step Three: Create an App

Finally we can create an app to hold a specific group of objects, where we can define the Models to hold the data and the methods for dealing with it.

1. Create the app

Django projects are structured into multiple ‘apps’ that define a specific part of the overall project, for instance a ‘books’ app in the case of a project that helps to reference a library’s collection of books, and separate apps for ‘cds’, ‘dvds’, and ‘members’.

Apps can be created by either manually creating a directory with the following files:

- __init__.py *       (This is tells Python to treat this as a Python module/package and is usually empty)
- models.py * (Contains definitions for the app’s models)
- test.py (For Unit/Integration tests - run with `python manage.py test`)
- views.py (Holds the app’s views)
- admin.py (For registering the models in the app in the admin site)

* Required

..or by running:

python manage.py startapp animals

..which will automatically generate the required files.

The app name must then be included in the INSTALLED_APPS list in the settings file (by default settings.py in the django_quickstart directory - see Note 2):

INSTALLED_APPS = [
...
"animals",
...
]

2. Create a model

Models can be thought of as being the nouns in your app, so in our case of an ‘animals’ app, you could add a model for a ‘Tiger’ and give it some properties, such as a name, and methods (essentially verbs) to give it something to do.

from django.db import models


class Tiger(models.Model):
name = models.CharField(max_length=255)

def __unicode__(self):
"""
Returns the default representation for the object
"""

return self.name

def speak(self):
return "Grrr!"

Django Fields

Django provides you with a number of fields that you can define the properties of a model with, such as CharField (limited text field), TextField (unlimited text field), EmailField, ImageField, and SlugField, which determine how the database schema should be set up and how the field should be displayed and validated in a form, https://docs.djangoproject.com/en/dev/ref/models/fields/.

Mixins for Multiple Inheritance

Often you want to reuse certain traits that are shared among different objects, in this case you can implement this very simply with abstract classes:

from datetime import date


# Implement the Mixins
class HasDateOfBirth(models.Model):
"""
Encapsulates the properties and methods for object that have a date of birth
"""

date_of_birth = models.DateField(max_length=8)

def get_age(self):
today = date.today()
born = self.date_of_birth
return today.year - born.year - ((today.month, today.day) < (born.month, born.day))


class CanRoar(models.Model):
"""
Encapsulates the methods for objects that can roar
"""


def speak(self):
return "ROOOAARR!!!"


# Add the Trait to the Tiger Model
class Tiger(models.Model, HasDateOfBirth, CanRoar):
...

3. Add the Model to the Database Schema

Run python manage.py syncdb to setup the database, this handles automatically creating tables in the database from the models. A third party app called http://south.readthedocs.io/en/latest/ can then be used to make additional changes.

Django Shell

You can play around with the model to try methods for creating a new instance and retreiving existing ones:

Run python manage.py shell then try the following:

Create an instance
>>> from animals.models import Tiger
>>> tony_the_tiger = Tiger(name='Tony')
>>> tony_the_tiger.save()
>>> tony_the_tiger.name
'Tony'
>>> tony_the_tiger.speak()
'Grrr!'
Retreive instances
>>> from animals.models import Tiger
>>> tigers = Tiger.objects.all()
>>> [<Tiger: Tony>]
>>> tonys = Tiger.objects.filter(name='Tony')
>>> [<Tiger: Tony>]
>>> tiger_1 = Tiger.objects.get(id=1)
>>> <Tiger: Tony>

Press ctrl-d to exit the shell.

4. And the Rest

By now we have a simple Django Project with an ‘animals’ app containing a Tiger model. With this basic setup it should be possible to discover how to create a more interesting view for displaying the tigers, (e.g. as a list of their names).

With the Django views documentation, as reference, the ‘Home’ view can be changed to return a rendered template with the list of tigers (Tiger.objects.all()) as a context property passed into it.

Notes

Note 1: Pip Freeze Command

The ‘pip freeze’ command can be used to get the currently installed packages and their versions. This can be redirected into a file from which you can later install them, for instance when setting up on another machine, as follows:

Redirect the output of pip freeze (with the required packages) into a text file:

$ pip freeze > requirements.txt

Install the required packages from the text file:

$ pip install -r requirements.txt

Note 2: Settings File

You can specify different files for Django’s settings, which is especially useful when you need to set up seperate environments, such as live, staging and dev.

Different settings files can be used using the –settings flag, for example:

$ python manage.py runserver --settings=django_quickstart.settings_live

Note 3: Database Migrations

Normally updating the database schema like this (by running syncdb again) is not a good idea, as any existing data will have to be reformatted to fit the new schema and any expected data (for instance a new field that is NOT NULL) would have to be made up for existing rows.

This is where database migrations are useful - allowing you to make changes to the database schema without worrying about many of the issues with schema changes. The references to these changes (in a directory called migrations) are also then uploaded to production or staging environments, allowing you to make the schema changes to these environments too with a simple command.

Prior to Django version 1.7 this was only available with a Third Party tool called South, however migrations have now been added to Django core:

https://docs.djangoproject.com/en/dev/topics/migrations/

..apparently thanks to some very generous backers on Kickstarter:

https://www.kickstarter.com/projects/andrewgodwin/schema-migrations-for-django

Some info on how South migrations work:

http://www.djangopro.com/2011/01/django-database-migration-tool-south-explained/