Introducing Django: Calling all Web Developers with Deadlines

Akash Mehta

OSDC Brisbane, 2009

Abstract

Django is a mature, Python-based web framework designed for non-trivial data driven applications. Described as the "web framework for perfectionists with deadlines", Django aims to enable developers to build high-quality web applications in record time.

With a unique architecture enabling serious code reuse, combined with a thorough templating toolkit purpose-built for web development, and an automatic administration site that actually works, Django is an extremely suitable framework for a wide variety of projects. After nearly five years of development, Django also has a fantastic community and greater depth of available resources than most PHP frameworks.

While getting started with Django is relatively straightforward, it can be quite a jump from other web development technologies. In this paper, I'll identify the fundamentals of Django, and demonstrate some of the features that make it a convincing solution for web development.

1 Introducing Django

Django is an application framework that drastically reduces the time required to build web applications. Powered by Python, Django takes a novel approach to application development that facilitates modular design and code reuse. In addition to design efficiencies, Django includes a number of game changing features, such as automatic (and robust) admin sites, ORM that's a pleasure to work with, and a new approach to URL design. In this paper, I'll introduce the framework and outline its feature set from the perspective of a general web developer.

2 Django History

Django was built in a production environment, to fill a need for a general purpose web application framework - similar to the Rails framework for Ruby. It was first released as an open source codebase in July 2005, by a team of developers using it at the World Online newspaper in Kansas, USA.

Django was designed for developers working on journalism deadlines. James Bennett, a maintainer of Django, often cites the example of a story on a public servant salary dataset being accompanied by a system to explore that same dataset - all ready and online within hours. Django takes a pragmatic approach to features across the board to achieve this, aiming to speed up development (and not just prototyping), while still producing robust web applications. The project motto is almost implied: "the web framework for perfectionists with deadlines."

3 Django applications: a new approach to web development

Django development, from a general perspective, works on the assumption that every project should be able to start out with minimal overhead, but scale up to significant functionality (and the related complexity). To this end, functionality in your web application is split into Django "applications", each of which serves a broad yet well-defined purpose. For example, a content-oriented site might include a core article serving application, as well as a blog application, and an application to search content managed by both of these.

To demonstrate the effectiveness of this application-oriented approach, consider the automatic administration panel of Django. The admin panel is not a core Django feature, certainly not in the same way as Rails' scaffold. The Django admin is implemented as a standard Django "application" that just happens to be bundled with core Django.

The admin panel requires authentication, and authentication functionality is provided by a separate authentication application that is also distributed with Django. Your own applications can (and should) make use of the provided authentication application; this is an extremely easy task. Your own applications also "talk" to the admin application to instruct it on which database tables it will be managing. Python itself is a great aid in facilitating this inter-application communication, and is another part of Django's success.

Other applications distributed with Django provide comments functionality, RSS feeds, "sitemaps" and more.

4 Django design patterns

With regards to design patterns, Django also roughly follows MVC (as implemented by web frameworks in general), with some different terminology. Jacob Kaplan-Moss, another maintainer of Django, describes the pattern as MTV - Model, Template, View.

Django models generally represent tables, and explicitly define the data they store. A model might look something like this:

class Post(models.Model):
  title = models.CharField(max_length=255)
  body = models.TextField()

A command line utility bundled with Django will take this model definition and automatically create a table of the current structure in the project's configured database. In addition to internals, this model data can also be readily used by applications. The admin system uses model definitions to generate reports and forms for managing data in these models.

Views form the next key component in a Django application, and are similar to controller actions in other major frameworks. In the context of other frameworks, a Django application can be thought of as having a single view with just enough functionality to serve the purposes of the application. Views are implemented with native Python functions.

Templates are the final piece in the puzzle; implemented with a syntax not unlike most popular , the template system offers developers just enough flexibility to generate output while restricting any significant business logic. Templates also play a key role in the Django's modular application system: a central templates folder (outside of application folders) allows developers to pull in functionality from other applications, while providing their own front-end templates, all without any modification to the third-party software.

Finally, Django provides an innovative pattern-based URL design system that decouples views (and other functionality) from a single URL, and (to an extent) centralises URL routing for a site. Each Django project has a root URL file that roughly resembles this:

urlpatterns = patterns('',
  (r'^clients/', include('client.urls')),

  (r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}),
  (r'^accounts/logout/$', 'django.contrib.auth.views.logout', {'next_page': '/'}),

  (r'^$', 'django.views.generic.simple.redirect_to', {'url': 'clients/'}),
)

In this project, a "client" application provides all URLs under "clients/", while the root "/" URL redirects to "clients/", and two other URLs are handled by views from Django's bundled authentication application. Under the "client" application folder, another URL pattern file provides URLs for the application:

urlpatterns = patterns('',
  (r'^$', 'client.views.index'),
  (r'^session/(?P\d)/$', 'client.views.session'),
)

In this case, this application is entirely unaware that its URLs are prefixed with "clients/"; the session pattern will match a URL similar to /clients/session/2/ and the "session" view under the "client" application will receive an argument named "session_id" with a value similar to int(2). Django templates can also make use of these dynamically-resolved URLs using the "reverse" function - this function will take a view name (e.g. "client.views.session" as used here), and any arguments, and generate a valid URL to that view based on the current URL configuration.

5 Included components

Following on from Python's "batteries-included" approach, Django ships with a number of applications, such as the automatic admin system, under the "django.contrib" module. As a side effect of being implemented as Django applications, the code for these components is very approachable for beginners, and diving into the code base by starting with the bundled applications is an effective approach to mastering Django.

5.1 Authentication

An extensible authentication framework is distributed with Django and located at django.contrib.auth. This application includes models for storing users and permissions, views to handle login/logout and password management, "decorators" to quickly wrap other views with access controls, and a collection of tools for integration and administration.

5.2 Administration

The administration application is a highlight of Django, and a game changer for independent web developers. The workflow for using the automatic administration sites is simple: design the database, write the Django models (generally one per table), identify the models to be administered to a helper function in the admin application, and optionally specify some additional details on how the data should be managed.

Django models provide a set of data types for fields that can roughly correspond to the HTML form controls a hand-made administration panel would use. For example, a field on a model can be identified as a date field; the administration application will display this as a single text field for manual date input, along with a date picker. Foreign keys become drop-down menus with available options taken from a target dataset, while many-to-many relationships become multi-select lists.

Automatic admin systems are not new; a search of any full-time PHP developer's projects will likely turn up at least one SQL DESCRIBE command for an on-the-fly administration system. However, Django takes this concept one step further, with an intuitive approach to describing the administration of models separate to the models themselves. This is achieved through a ModelAdmin object named after the model - a blog application might have a Post Model object and a PostAdmin ModelAdmin object. These ModelAdmin objects can describe fields to be excluded from the admin panel, default sorting options, additional functionality to be made available via the admin, formatting and functionality for the display of lists of records, and even links to the record being edited in another area of the project. All of these customisations are entirely optional, and use logical defaults to provide significant administration power by default.

Kaplan-Moss cites project workflow options as a key advantage of the Django admin system: with an involved project contact / domain expert, the admin system can be used to verify the validity of a database design. Once the database design is considered correct, the project contact / domain expert can then enter data into the database while a developer builds the front-end views for the system. Given Django's speed of development, a developer can have a prototype ready and displaying realistic data within hours.

5.3 Syndication

The syndication application provides a general API for generating and displaying RSS or Atom feeds. A high-level framework allows feeds to be created with minimal code, with a focus on data retrieval and not feed markup. Developers provide the syndication framework with a feed generator, a simple version of which might resemble this:

class LatestEntries(Feed):
  title = "Chicagocrime.org site news"
  
  def items(self):
    return NewsItem.objects.order_by('-pub_date')[:5]

In this example, the items method returns a list of row objects from the Django database framework, and will be called by the syndication framework as needed. Returning a database resultset is not required and the syndication framework will accept any Python objects. Passing objects between components is standard in Django development, and Python's object model provides significant flexibility in this respect.

Appendix: Further reading