At the Forge - First Steps with Django
When I first began developing Web applications, I did most of my work in Perl, and my programs were invoked via CGI. My preferences have shifted somewhat over the years, first toward component- and template-based systems, such as Mason and Zope, and then toward all-encompassing frameworks, such as OpenACS. Most recently, I've been spending time using Ruby on Rails. As a longtime Perl programmer, I've been pleasantly surprised by both the Ruby language and the Rails framework.
But, of course, Ruby isn't the only popular language out there, and Rails isn't the only popular framework. One of the biggest rivals to Rails during the last year or two has been Django, a Python-based framework with many of the same goals as Rails. Django was first written by Adrian Holovaty while working for a newspaper in Lawrence, Kansas. Holovaty now works for the Washington Post, but he continues to work on the framework along with a host of other open-source contributors.
It would be misleading to say that Django is a Python port of Rails (or vice versa). But, there are many similarities between the two projects. Both Rails and Django grew out of successful commercial projects, the former at 37 Signals and the latter at a newspaper. Both aspire to make Web development fun and easy, removing as much of the drudgery as possible from such work. Both use the model-view-controller (MVC) paradigm for handling actions and creating pages. Both use a particular programming language throughout the system for code and configuration files. And, both have managed to rally a large following, ensuring that they both will continue to be developed for some time to come.
This month, then, I begin a trip into the world of Django to see exactly what it is about this framework that excites people. Even if you're never going to create anything in Django, or you dislike the Python language, I expect there will be something that Django can teach you, or at least make you think about.
The main Web server for Django is at www.djangoproject.com, and you can download a version from there for your own computer. At the time of this writing, the latest official version is 0.96. You can download that version in a .tar.gz file, or you can live on the edge a bit, getting the latest development version via Subversion (svn). I chose the latter path for this column, although if I were working on a commercial site, I might well prefer the stable version.
As is the case with Ruby on Rails, the Django code is not a skeleton Web site, so it should not be placed under a directory that is publicly viewable via the Web. Rather, the code should be installed like any other set of Python libraries and programs on your server, using the standard Python install routine:
python setup.py install
Once this installation is complete, you can use it to create one or more Django projects. The terminology here can be a bit tricky, especially if you're coming from the Rails world, so be careful. A Django project contains one or more applications. Each application then contains sets of models, views and templates. An application can be reused across multiple projects—something like plugins or engines in Rails. For example, you can imagine a calendar application that is used by multiple projects and a portal project that uses several applications (for example, calendar, e-mail and RSS reader) that come from elsewhere.
This means that when we create our Django project, we aren't yet ready to display any code to the world. Rather, we need to create a project and at least one application within that project if we are to see any dynamic output.
Let's create a site (named mysite in the Django tutorials, so I use the same convention here):
django-admin.py startproject mysite
When I installed Django on my Ubuntu box, it placed the administration program django-admin.py in /usr/bin. Your system might have it in a different location, so you might need to modify your PATH to get the above to work as written.
Starting a project in this way creates a directory named mysite, containing four Python source files, each with a .py extension:
A blank __init.py__ file: whenever a directory contains __init.py__, Python sees the entire directory as a single package. So long as the file exists, even if it's blank, our project will be considered a package.
settings.py: this file does not contain executable code, but rather configuration settings for the Django instance. For example, we soon will modify this file to indicate the location and type of relational database that we're using.
urls.py: this is where we will associate URLs to functionality, using regular expressions to match URLs. If you're coming from the Rails world, this is similar in many ways to config/routes.rb.
manage.py: this is a catchall management program for a Django site, handling a large number of administrative tasks, such as starting, stopping and synchronizing the project.
Once again, don't make the mysite directory visible to the world via the Web. Rather, we will expose parts of this directory to the world through our Django project.
If you're coming from the world of Ruby on Rails, this might seem like a very small number of files to begin with. (Out of the box, Rails creates a large number of files and directories.) But, this is because we haven't really created any applications yet, only the package (or container, if you will) that will control and use the application.
The package does have its own HTTP server though, in the same way that Rails comes with one. We can test that things are in order, at least at the package level, by starting up that HTTP server:
python manage.py runserver
This is the first time that we use manage.py, but it is far from the last. The server, which will be running only on the localhost address (127.0.0.1), indicates that the basic framework is up and running and that you now should move ahead with the database definitions.
On the server side, we get the following messages:
Validating models... 0 errors found. Django version 0.97-pre, using settings 'mysite.settings' Development server is running at http://127.0.0.1:8000/ Quit the server with CONTROL-C.
The first two lines indicate that our models—the files with which we describe the contents of our relational database tables—don't exist, which means that they generate 0 errors. (Don't worry; we'll be adding new models, and thus errors, in the near future.) Django also is nice enough to provide version information to indicate the file from which settings are being taken and how we can quit the server.