At the Forge - Django Views and Templates
Last month, we began looking at Django, a popular framework for creating Web applications in Python. Django has the reputation of being the “Ruby on Rails of the Python world”, and there is some justification for that description. Even though Django was developed in parallel with Rails and has many unique features that distinguish it from its Ruby counterpart, it's difficult to avoid comparing the two.
In the introduction to Django last month, we saw a number of subtle, but important, differences between the two systems. Django handles a “project” at a time, where each project may contain one or more applications. This contrasts with the Rails approach, in which there is no real equivalent to Django's projects, because everything is an application.
We also saw that Django comes with a built-in Web-based administrative system. It takes a tiny bit of fiddling with a configuration file to activate this administrative system, but it provides a great number of benefits to any system that uses it.
Despite their differences, both Django and Rails use an approach that is best known as MVC (model, view, controller) developed in the Smalltalk community but adopted by many other languages and frameworks since then. These terms, used verbatim in the Rails world, are called models, templates and views in the Django world, and they form the bulk of a Django-based site.
This month, we work with templates and views, ignoring models and the database API until next month. But, don't worry; Django's templates are quite powerful, and they provide an interesting lesson in restraint.
Our first step involves creating a new application within our project. For a number of reasons, including the simplicity with which we can create a page, our example application is a very simple blog program. We create our blog application by switching into our project directory, and then by using our management program, manage.py:
$ cd /opt/atf/mysite $ python manage.py startapp blog
If this executes successfully, Django won't print any messages. Rather, we can get a listing of the current directory, which should now include a blog subdirectory:
$ ls blog __init__.py models.py views.py
Django is smart enough to stop us from creating an application twice, if we try to do so:
$ python manage.py startapp blog Error: [Errno 17] File exists: '/opt/atf/mysite/blog'
Now, let's create a simple “Hello, world” view, just so we can demonstrate that things are working. Thus, we open blog/views.py, which starts off empty except for a comment indicating that this is the file in which views are defined.
The simplest possible “Hello, world” view will be called index, acting sort of like the index method in Rails or the index.html file on a Web site—providing the default content when no specific method is invoked for an application. We also have to import the Python module in which Django's HTTP response capabilities are defined. When we're done, the entire views.py file looks like this:
from django.http import HttpResponse def index(request): return HttpResponse("Hello, world.")
If our server isn't already running, we can start it with:
python manage.py runserver
Or, if we want to run on a publicly accessible IP address, rather than 127.0.0.1 (“localhost”), we can do something like this:
python manage.py runserver 22.214.171.124:8000
To see the output from our view, let's point our browser to the following URL, expecting to see “Hello, world”: http://126.96.36.199:8000/blog/. Instead, we get an error message, indicating that Django has no idea what we're talking about. The good news is that this error message, which is turned on only when we are developing an application, tells us what we did wrong—namely, that our URLConf definition failed to have any entry for blog in it.
This is a fundamental difference between Django and Rails, and it reflects the different philosophies of the two communities. In Rails, you expect the system to do the right thing by default; you should have to say something only when it deviates from that norm. In contrast, Django assumes that you want to make everything explicit.
Among the things that you need to make explicit is the way in which URLs are translated into method calls. The Django system for doing this is called URLConf, and it is a set of regular expressions defined for the entire project. (It functions something like routes in Rails.) If you are familiar with regular expressions, it should be pretty easy to add or modify URLConf.
For example, let's say we want the /blog/ URL to go to our blog application. So, we would open the URLConf file, which for the mysite project will be in mysite/urls.py. (We already modified this last month, when we added administrative capabilities to our Django site.) We then add a line that looks like the following:
In other words, if the system sees a URL that begins with blog and ends with /, it should invoke the index method within views.py in our blog application. And, sure enough, as soon as we save urls.py to disk, we can reload our URL http://188.8.131.52:8000/blog/, and in our browser, we see “Hello, world”. Our Django application is starting to come together.
Pick up any e-commerce web or mobile app today, and you’ll be holding a mashup of interconnected applications and services from a variety of different providers. For instance, when you connect to Amazon’s e-commerce app, cookies, tags and pixels that are monitored by solutions like Exact Target, BazaarVoice, Bing, Shopzilla, Liveramp and Google Tag Manager track every action you take. You’re presented with special offers and coupons based on your viewing and buying patterns. If you find something you want for your birthday, a third party manages your wish list, which you can share through multiple social- media outlets or email to a friend. When you select something to buy, you find yourself presented with similar items as kind suggestions. And when you finally check out, you’re offered the ability to pay with promo codes, gifts cards, PayPal or a variety of credit cards.Get the Guide