Recently I decided to check out Django 1.3 and in the process of doing it put together a short tutorial to illustrate some of the basic features of Django and some basic JQuery. In order to follow along you should have a fundamental understanding of python, javascript, jquery, html and css.

The application that this tutorial will build is called WordConfusion, it’s a very simple quiz game that uses wiktionary word-of-the-day words matched with their defintions.

Using javascript/JQuery is just one way to create a quiz like this and although django may not be the best web framework for a game it works well for a quick prototype. If you are looking for a fun introduction to Django this might be a good way to get your feet wet.

Setting up the development environment

I’m going to be working on a Linux workstation, vim as an editor and some opensource tools like Gimp and ImageMagik.

This won’t cover installing Django, the best way to do this is to use virtualenv and pip.

Projects and applications

A Django “application” is a set of related functionality used to maintain or complete one aspect of a site. Ideally an app is re-usable and for a larger site an app may be limited to a well defined problem with limited scope.

A Django “project” is nothing more than a collection of applications, a settings file, and URL definitions.

For wordconfuse, we will be creating one project and one application and the application will contain all of the functionality for the site. It’s structured this way because the scope of the application is limited to playing the game and the business logic is limited to keeping track of scores. You might imagine a more sophisticated flashcard program that allows individuals to keep track of their own decks, add comments, etc. In that case the number of applications would likely be more than just one.

Creating the project and the wordconfuse app

Now that Django is installed the project for wordconfuse can be created.
For this example name of the project will be “tutorial” and the app will be “wordconfuse.”

cd ~
django-admin.py startproject tutorial

This creates a “tutorial” directory and copies a few files in it for configuring Django applications.

  • manage.py – script that sets up the application, manages the database, runs unittests and does other administration tasks. It will also be used to start the development server.
  • settings.py – all of the settings for the Django project, this will need to be customized for your web server and project directory structure.
  • urls.py – this specifies URL handling for Django and will have regexes that will dispatch requests to the webserver to specific views.

Normally we would use the manage.py script to create the wordconfuse application.
In this case however, it will be easier to clone the application from github.

cd tutorial
git clone git://github.com/jarv/wordconfuse.git

This creates a “wordconfuse” directory with all of the application files in it.
If you have worked previously with web frameworks Django may look similar to MVC (model view controller) though its naming convention is slightly confusing. What Django uses is an “MVT” framework (Model, View, Template) where the “Model” describes how your data is structured, the “View” controls what data is presented, and the “Template” is the presentation layer.

  • wordconfuse/views.py – Defines functions that manipulate and query data structures defined in models.py. These will handle the business logic when requests made to the server and dispatch them to the appropriate dynamic html templates.
  • wordconfuse/models.py – For the wordconfuse application there are only a couple data structures needed for the game. One is for recording games that are completed to keep track of highscores and the other is a list of words and definitions needed for the game.
  • wordconfuse/templates/* – Using the django templating language this directory contains multiple html, css and javascript files that are dynamically generated.

Configuring Django – settings.py

Before starting the app there are several basic things that need to be configured:

  • Setup a local db (sqlite)
  • Add the app to settings.py
  • Tell Django about the template directory
  • Tell Django about the directory that contains static files
  • Customize urls.py for URL dispatch

Adding the “wordconfuse” app

The first change to settings.py is to add “wordconfuse” to the list of INSTALLED_APPS. Search for INSTALLED_APPS and add “wordconfuse” to the list. In addition to adding the app at the top of settings.py the python path is modified to add the project directory to it.

# Django settings for tutorial project.
import os, sys
PROJECT_ROOT=os.path.dirname(__file__)
sys.path.insert(0, PROJECT_ROOT)

...

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'wordconfuse',
...

Directory for template files

Next, add the the location of the templates to settings.py. For this project the template area is located under the application dir. Normally this is not a good idea but in this Django project there is only one application so it won’t matter.

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.
    '/path/to/tutorial/wordconfuse/templates',
)

Static Files (new in 1.3)

Django 1.3 introduces many new features, two of them we will be using for this game are class based views and the handling of static files.

Websites typically consist of both dynamically generated content and static content such as images, css, javascript, etc. Django’s templating language allows us to use the macro {{ STATIC_URL }} to specify the location of our static files. This is extremely useful as it gives you the freedom to move the location of our static files without the need to touch template code.

There are two directories that are created for static files.
One directory will be under our application where we will copy the files we need. The other is the site-wide directory where all static files will be deployed.

The first directory will already be present since it is part of the application that was downloaded earlier. The second directory will need to be created:

mkdir ~/tutorial/staticfiles

In settings.py let Django know about the directory where static files will be deployed for the site.

STATIC_ROOT = '/path/to/tutorial/staticfiles'

In urls.py you will need to import the staticfiles_urlpatterns class and add a URL handler for development server. Do this by adding an import statement to the top of the file and adding to urlpatterns at the bottom:

from django.contrib.staticfiles.urls import staticfiles_urlpatterns
..
urlpatterns += staticfiles_urlpatterns()

Once the static file area has been created run the “collectstatic” command to copy the application static files into the deployment directory.

cd ~/tutorial
python manage.py collectstatic

If static files were setup properly you should see output indicating a large set of files were copied to the site-wide static directory.

urls.py and class based views (new in 1.3)

One common pattern in a Django application is to render a template without any data manipulation. This is the simplest use of class based views and is what we will be using for the main page of the wordconfuse app. The document root URL for wordconfuse fits this model as it only returns a template for the main index page which renders dynamic html, css and javascript.

Besides the default view there are other URLs that need to be defined. These URLs will be
requested by the javascript rendered on the main page.

  • get_words – returns json data for ten questions and answers to create the quiz
  • gameover – his requested when the game is over via an ajax POST from javascript
  • new_hs – if a finished game results in a new highscore this URL will be requested if he wants to associate a username to it
  • hs – this returns html for the highscore table

Modify urls.py again so that there a new import statement at the top to bring in the TemplateView class and add the view names listed above to urlpatterns:



...
from django.views.generic import TemplateView
...
urlpatterns += patterns('wordconfuse.views',
        (r'^$', TemplateView.as_view(template_name="index.html")),
        url(r'^get_words$', 'get_words', name='get_words'),
        url(r'^gameover$', 'gameover', name='gameover'),
        url(r'^new_hs$', 'new_hs', name='new_hs'),
        url(r'^hs$', 'hs', name='hs'),
        )
...



Database Setup

In settings.py setup the database backend to use sqlite3 and give it a descriptive name. In this setup I used django_db.sqlite3.wordconfuse

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'django_db.sqlite3.wordconfuse',

Once the database is configured it can be created using the manage.py script. If this is the first time you are running syncdb it will ask you configure the auth system. Answer ‘yes’ and follow the prompts to create a new superuser.



cd ~/tutorial
python manage.py syncdb

Creating tables ...
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_user_permissions
Creating table auth_user_groups
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table wordconfuse_gamescores
Creating table wordconfuse_words

You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use '<your username>'): 
E-mail address: <your email>
Password: 
Password (again): 
Superuser created successfully.
Installing custom SQL ...
Installing indexes ...
Installed 3935 object(s) from 1 fixture(s)


This will create the default tables and the two application tables “wordconfuse_gamescores” and “wordconfuse_words” in an sqlite3 db. The “wordconfuse_words” table will automatically be populated with the word and definition data by loading a fixture in the application directory.

Starting the development server

Now that Django has been configured you can start the development server to test the game in your local environment.


$ cd tutorial
$ python manage.py runserver

Validating models...

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


If everything was configured properly at this point you should be able to connect your browser to localhost:8000 and play the game.

Summary

In this intro we have setup the wordconfuse game and also presented a short introduction to Django.
In part 2 we will look at the application models and views in more
detail and the overall structure of the game design.



18 Responses to “Django 1.3 / JQuery tutorial – Making a flashcard game (Part 1)”

  1. There are some errors in the code you’ve provided – html artifacts such as:

    from django.views.generic import TemplateView

    urlpatterns += patterns(‘wordconfuse.views’,
    (r’^$’, TemplateView.as_view(template_name="index.html")),
    url(r’^get_words$’, ‘get_words’, name=’get_words’),
    url(r’^gameover$’, ‘gameover’, name=’gameover’),
    url(r’^new_hs$’, ‘new_hs’, name=’new_hs’),
    url(r’^hs$’, ‘hs’, name=’hs’),
    )

    where template_name=”index.html” instead of " etc.

    • 2 jarv

      thanks, had some trouble with the WP sourcecode plugin html-escaping some characters. should be fixed now.

      • 3 dtc

        hi

        trying out your tutorial or at least just running django for the first time. still having problems, i dont know if its because of that set of lines. everything else seems to work. i get “Error during template rendering” while trying to run the server.

  2. 4 kam

    This is the best tutorial I have found in a long time in my study of python and django.

    Pruzing your site presents you a very intelligent and talented young man.

    Your work is very inspirational, Thank you very much. Wish you all the best.

  3. 6 James

    Amazing! It worked like a charm.
    I had no problems installing, except one: the initial_data.json gives me error when i try to syncdb, to fix it just syncdb twice and delete the .json file from fixtures folder, it’ll work 100% after that…

    Thanks!

  4. 7 John Dey

    Unfortunately, I did not follow instructions correctly by not including hs line in url.py. How do I remove my questions and comment from this tutorial so as not to confuse anyone?

  5. 9 Rick

    Loving the tutorial, Jarv! Thankyou.

    One thing for newbies to watch out for – at least with Django 1.4 – is that ‘cd ~; django_admin.py startproject tutorial’ creates a nested pair of ‘tutorial’ directories under your home:

    ~/
    ~/tutorial/ < outer wrapper (can be renamed). contains project directory as well as application directories, and the site-wide static files directory.
    ~/tutorial/tutorial/ < actual project directory containing urls.py, settings.py etc.

    I find this confusing! And indeed got the tutorial directories mixed up in my first time through the tutorial.

    I rename the outer wrapper as something like 'tutorial-wrapper' as a reminder to myself to make sure I'm in the right place.

  6. I just wrote a blog post on how sketching a diagram of a codebase can help you figure out how things flow, especially with complex multi-layer web apps. I used wordconfuse as an example and you can see a diagram of how the app works here:

    http://richardboardman.com/2012/04/unravelling-the-anatomy-of-a-website-visually/

    I hope this will help others following through this great tutorial, especially if they are new to JQuery like I was!

  7. 12 Pradnya

    But there is problem , To get new list of words, we need to refresh the page …can this be improved. ?…I tried to use the same concept in myproject but we need to refresh the page ………otherwise it loads the contents 4m the cache…even if cache is set to false.

  8. 13 Rems

    Hi,

    might want to state to clone through :

    git clone https://github.com/jarv/wordconfuse.git

    The command you give provided me with :
    (flashcard)dev@mekong:~/PROJECTS/tutorial$ git clone git://github.com/jarv/wordconfuse.git
    Cloning into wordconfuse…
    github.com[0: 207.97.227.239]: errno=Connection refused

    • 14 Rems

      Awesome work anyhow, very satisfying to get it to work in 5 minutes top. :)

  9. 15 Bsizzle

    Hi – I’m struggling just to get this working on Python 2.7 and Django 1.4.2. I saw the comment about staticfiles collection not working, so I made the adjustments suggested by Rick, but still no dice. So I have an outer project folder:

    base_url/tutorial-wrapper

    and in that folder have the following folders and files:

    staticfiles
    tutorial
    wordconfuse
    manage.py

    where tutorial has

    settings.py
    urls.py
    wsgi.py

    I changed all the settings.py and urls.py parameters (that sit in folder ‘tutorial’) as requested. When I run the collectstaticfiles command, I am first prompted with:


    You have requested to collect static files at the destination location as specified in your settings.

    This will overwrite existing files!
    Are you sure you want to do this?

    Type ‘yes’ to continue, or ‘no to cancel: yes ### <- Bsizzle types in that 'yes'
    Copying '(Bsizzle's base url)tutorial-wrapperwordconfusestaticimgbetterlucknexttime.png'
    Traceback (most recent call last):
    File "manage.py", line 10, in
    execute_from_command_line(sys.argv)

    There are many more lines in the traceback but I hope that illustrates my problem. Any ideas friends:)?

    • 16 Bsizzle

      Never mind. The issue I had was a forward/backslash issue. It was ok otherwise:) So consider the above an explication of what Rick said:) And Thanks Jarv!


  1. 1 django | Pearltrees
  2. 2 25 jQuery Tutorial Plugin October 2011 | Web Development and Design Blog