Introduction to Django: Helping Perfectionists With Deadlines
Got something to say?
Share your comments on this topic with other web professionals
In: Articles
Published on April 22, 2008
Django is an open-source Web framework, written in Python, that allows you to easily and rapidly develop interactive, data-centric web applications. It came into being when two Web developers—Adrian Holovaty and Simon Willison—in Kansas, after moving their newspaper’s website from PHP to Python, found themselves repeatedly solving similar problems. They decided to extract the common functionality and released the resulting framework in 2005.
Python
Python itself is an interpreted programming language that belongs to the same class of languages as Ruby, Perl and, to some extent, PHP. It wasn’t designed specifically for writing web applications like PHP was, but it is a very flexible, easy-to-learn, object-oriented language that can be applied to many tasks. The one thing you’ll notice about it right away is that it uses indentation rather than braces for blocks of code. If you’re anything like me, that might put you off until you try it and realize that it makes code a lot more readable. Python’s motto is batteries included, which refers to the wealth of modules available in the standard library, a large proportion of which is devoted to handling various internet protocols. The Python website has lots of useful information for beginners.
How Django applications are built
For a typical working application you need to create three things: a data model, at least one view, and a URL mapping.
- The data Model describes the kind of objects your application stores and displays—an online store might have customers, products, categories, orders, payment types, shipping options, etc. Each model has attributes, such as a name and address for a customer, and a title, description, and price for a product. If you have been exposed to any object-oriented programming these will be familiar concepts, but if you haven’t, don’t worry, it’s not a pre-requisite.
- Views are bits of Python code that decide how to respond to a request from a browser and create an appropriate response, which is most often a page of HTML.
- Finally, it is the URL mappings that determine which view will be used. For example, you might decide that `/` is handled by a view called `index`, and `/products/` is handled by a view called `all_products`. It gets really interesting when you start using arguments. Instead of having a URL like `http://example.com/display_product.php?product=123` (which, let’s face it, is just plain ugly) you can have a URL like `http://example.com/products/123/` and have Django use the `product_detail` view with an argument of “123”. You are then free to pull product 123 out of the database and create an HTML page with information about it. This doesn’t just make URLs look prettier (which is a bonus in itself), but has a number of other benefits. Tim Berners-Lee, the creator of the web, wrote about this in his essay Cool URIs Don’t Change.
Interacting with your data
Like other frameworks, Django uses a model-view-controller paradigm where your data model, logic, and presentation are separated. Your logic is written in Python and your presentation is written as templates (typically HTML, but they can be any textual format). Although your data is stored in a relational database (Postgres, MySQL, Oracle, and SQLite are all supported), Django actually lets you define your data model using Python classes, then lets you manipulate your data using those classes. For example, here’s how part of the model for an online store might look:
class Product(models.Model): name = models.CharField(max_length=100) description = models.TextField() price = models.IntegerField() def __str__(self): return self.name class Customer(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30) email_address = models.EmailField() cart = models.ManyToManyField(Product) def __str__(self): return "%s %s" % (self.first_name, self.last_name)
The str methods are just there to return a human readable representation of an instance. With such a definition, Django’s object-relational mapping will automatically translate between Python objects and the appropriate SQL statements to query and manipulate the database. You can even do so interactively from the Python interpreter, as in Figure 1:
As you can see, you barely need to think about databases at all, let alone write any SQL. That’s not to say you can’t, because you get the option of using your own SQL queries if you need to, but this will rarely be the case since Django can elegantly construct complex queries for you. As an example, the following returns all products that contain “t-shirt” in their name or are more expensive than $10.00.
>>> Product.objects.filter(name__contains="t-shirt") | Product.objects.filter(price__gt=1000) [<Product: Blue t-shirt>, <Product: Red t-shirt>, <Product: A toy for the demo.>]
Displaying your data
So we’ve seen how to access our data in Python, but how do we get it into a web page? Like other frameworks, Django provides a template system that allows you to format your data as HTML. Let’s say you wanted a page that, for a given customer, lists all the items in their cart. To keep the example simple, we’ll just create a very plain page. Here’s what your template might look like:
<html> <head><title>{{customer}}'s cart</title></head> <body> <p>{{customer}} has the following items in their cart:</p> <table> <tr><th>Item</th><th>Price</th></tr> {% for item in customer.cart.all %} <tr><td>{{item.name}}</td><td>${{item.price|floatformat:2}}</td></tr> {% endfor %} </table> </body> </html>
It’s mostly just familiar old HTML, but notice the extra bits in braces, called tags. The ones that look like {{this}}
are variables, and the ones that look like {% this %}
are blocks. In this example, customer
is a variable that will be given to the template when it is rendered, so {{customer.cart.all}}
becomes the contents of the customer’s cart. The block tag {% for item in customer.cart.all %}
is a for loop. It repeats the part of the template between it and the {% endfor %}
tag with the variable item
set to each object in customer.cart.all
. So for a cart containing three products, the template will create a table with one header row and three data rows.
Take a closer look at the price column. If you’re familiar with Unix shells, you might think that looks like a pipe, and indeed it is a lot like that. The variable item.price
is filtered through the floatformat
filter, which is given an argument of 2—the number of decimal places. You can see the result of this in Figure 2:
Django provides dozens of tags and filters as standard, and if you know your way around Python you can add your own.
The admin site
When you write a web application, one of the first things you need to do is create forms and logic for adding data to work with. This can be a significant chunk of work at a time when you want to be writing the public-facing pages (the fun part!). One of Django’s most useful and impressive features is that it will dynamically create an entire admin system based on your data model(s). All you need to do is enable it and decide what URL you want to point there—then go ahead and manage your data! You can see an example of this in Figure 3:
Other features
Django has a number of other features that aid the creation of real-world web applications. One is internationalization, which is an important and tricky topic that site developers are becoming more and more aware of. If you mark your text strings in your code and templates as being translatable, Django’s make-messages utility will create a translation file for all those strings. These are simple text files that you can have your translators fill in. When it comes to displaying a page to the user, the language selection is made automatically. If the browser states the user’s preferred language and there is a translation for that language, that one is used, otherwise the configured default is used.
If you have a particularly high volume site, the cache framework can give you a big performance boost by trading off speed for the dynamic nature of your site. If you have a page that is costly to generate, but doesn’t change very often, you can tell Django to cache it. The first time someone access that page it will be generated in the normal way, but stored in the cache. Subsequent requests take the page straight from the cache instead of generating it again, and this continues to happen until the page expires, after which the next access causes it to be generated again. This is useful for things like blogs and news sites, where content is viewed far more often than it is updated. You can choose from a number of cache storage options, including memcached (as used by sites like Slashdot and Wikipedia), database, and files.
Community and extensibility
The automatic admin site, discussed earlier, is one of Django’s contrib packages. These are extra bits of functionality that aren’t part of the Django core. While Django would work fine without them, they nevertheless make life easier. Some other contrib packages of note are:
- The syndication framework, which makes it ridiculously easy to publish RSS and Atom feeds. If you had, say, a model called BlogEntries, you could create an RSS feed that people could subscribe to in about ten lines of code.
- Another contrib package offers automated protection from a class of security vulnerability called Cross Site Request Forgery. The `csrf` add-on adds a hidden field, with a value based on the user’s session ID and a secret key, to any forms you create. When the form is submitted back to Django, this add-on makes sure it contains the hidden field with the correct value. This ensures that form submissions come from forms that Django generated. It can do this because Django provides a middleware facility that allows extensions to manipulate requests and responses.
- Because of Django’s clean extensibility and the dynamic nature of Python, creating add-ons is not difficult and the open source community has created many. There exist packages for tagging, user registration (with e-mail address confirmation), forums, displaying and checking captchas, voting, displaying and managing photos, and interfacing with OpenID. If you’re creating a website, you might find that a lot of the work has already been done for you.
- One particularly large extension that can be considered a product in its own right is Satchmo, which is an open source software based on Django for creating online stores. In addition to all the features you already get with Django, Satchmo provides you with all the additional functionality you need to sell online: a flexible data model for products and customers; payment handling; shipping options including UPS integration; searching; newsletters; internationalization; dealing with discounts and tax; and generation of PDF invoices and shipping labels.
Installation and deployment
To get up and running with Django you’ll need Python, Django itself, and a database. To begin with it is definitely worth using SQLite for your database. It requires no setting up, and keeps its database in one file. If you’re using Linux, your distribution probably has packages for these. If you’re using Windows, it’s a little more work, but the Django on Windows page has a handy step-by-step guide.
When you want to create a new Django project, you use the django-admin
command to create a skeleton project in which you can create your applications. New projects and applications start out with placeholder files for you to create models, views, and URL mappings. During development you can use the built-in web server to serve your files.
When it comes to deploying your application for production use, as well as moving to a more capable database such as Postgres or MySQL, you’ll want to stop using the built-in web server. The officially preferred deployment scenario is to use Apache with mod_python. mod_python is an Apache module that embeds a Python interpreter within the web server. Depending on the flexibility of your hosting company, this might not be possible. Other options are using FastCGI, which is available on many Web servers (including Apache, lighttpd and Microsoft IIS), SCGI and AJP. These last three, particularly FastCGI, are often the only options available when using shared hosting, but they still give good performance. A list of Django friendly hosts is maintained on the Django project’s wiki.
Summary
So that’s the basics of Django. For more information, see the Django Project website. If you’re starting a new web application, you should certainly consider it as your framework, especially if you’re already familiar with Python. Even if you’re new to both Django and Python, the learning curves of both are shallow enough that you can almost discount them and just compare based on features. One recent development that is likely to increase the usage of Django is Google’s announcement of their App Engine. The first language to be supported is Python, and Google has published an article called Running Django on Google App Engine. It’s a little different to vanilla Django, so if you’re interested in this option you’ll need to check their documentation.
Related Topics: Scripting, Programming, Content Management Systems (CMS), Content
Dan Ellis has been a software engineer, network engineer and web developer, all of which are to blame for him not being a rock star. He can currently be found fighting off evil hackers in his day job, and finding any excuse he can to write Python.