Thursday, April 22, 2010

Django + Dojo

When I work on HTML projects, I usually use the Dojo Toolkit for my Javascript needs. Lately I've been spending some time playing around with the Python web framework Django. I did some internet searching and found Dojango, a project that integrates Django with Dojo. Dojango has features for automatically turning Django form fields into Dijits (Dojo UI widgets), but unfortunately Dojango uses Dojo's custom HTML attributes with Dojo's parseOnLoad option. I prefer to create Dijits programatically so that my markup stays clean. I decided to develop a Django app to meet my needs.

Code is available from SVN. Instructions are below.



# Setup app in

# Required attributes:

# The URL to get dojo.js from
DOJO_URL = MEDIA_URL + 'js/dojo'

# Optional attributes:

# Set to True to add Dojo setup to template

# Set Dojo theme
DOJO_THEME = 'tundra'

# Set the value of djconfig
DOJO_DJCONFIG = {'isDebug': False, 'parseOnLoad': False,
'modulePaths': {'app': MEDIA_URL + 'js/app'}}

# More on this later

# Attach middleware

The dojo object

The middleware attaches a Dojo object to each request. You can access the object from your views, and use it to set Dojo parameters.

# The dojo object has several useful attributes and methods.

# The path to dojo.js (from settings.DOJO_URL), read-only

# Theme
request.dojo.theme = 'soria'

# DjConfig
request.dojo.dj_config['isDebug'] = True

# Convenience method to set module paths in dj_config
request.dojo.set_module_path('custom', 'url_to_custom_module')

# Add stylesheets

# Require modules

# Set function to addOnLoad
request.dojo.append_aol('function() {do_something();}')

# Set function to addOnLoad before other already set
request.dojo.prepend_aol('function() {do_something();}'


Django forms can easily be 'dijitized'.

from dojo import models as dojo

class Register(forms.Form):
username = forms.RegexField(
label='Choose a username (letters and numbers only)',
'invalid': 'Username must be 16 characters or shorter, and can only'
' contain letters, numbers, underscores and dashes.'

# Use the dojo_field function to attach dijit
# parameters to a Django form field.
dojo.dojo_field(username, 'dijit.form.ValidationTextBox')

dojo_field arguments

* field - Django field to attach dijit parameters to.
* dojo_type - str, the qualified name of the dijit class to use

* attr_map - dict, Used to map Django field parameters to Dijit parameters.
Overrides the default values in dojo.models.default_attr_map.
The dict elements should be structured as follows:

Key == Django attribute name
Value == tuple with elements:
[0] == Dijit attribute name to map to
[1] == None, or callable to convert Django value to Dijit value

'max_length': ('maxLength', None),
'regex': ('regExp', lambda a: '%s' % a.pattern)
* dojo_attrs - dict, Attributes will be applied directly to dijit.
Key == dojo attribute name
Value == dojo attribute value

After creating a form, it must be instrumented to create the Javascript required to create the dijits.

def my_view(request):

my_form = Register()

# This call generates all the necessary Javascript code

# By default, the function code generated
# is a string to be added in-line.
# If you prefer to call a pre-defined JS function,
# just set the request.dojo.form_function attribute.
# The value of the attribute should be a tuple where:
# [0] == qualified Dojo module name where function exists
# [1] == function name
# request.dojo.form_function can also be set automatically
# by setting DOJO_FORM_FUNCTION in


Include the following tags within the 'head' tag of your HTML template:

{% load dojo %}
{% dojo request.dojo %}

The Dojo app also includes a script for creating a Dojo build:

python dojo_build

1 comment: