Install Django and Build Your First App

In our Introduction to Django, we covered all the basics of using the open source web-building framework. If you haven’t read through our beginner’s tutorial, go ahead and do so now. If you’ve already made it through the easy stuff, you’re probably ready to dive into some code and start building — so let’s do it.

Our first step is to grab a copy of Django and set up a development environment where we can tinker away.

Once all the files finish downloading, we need to make sure our local Python installation is aware that Django exists on our machine. There are a couple ways to go about that, but a symbolic link to your Python site packages directory is probably the easiest.

Assuming you’re on a *nix system, this line will do the trick:

ln -s `pwd`/django-trunk/django /path/to/python_site_packages/django

If you don’t know where your Python site directory is, here’s a handy bit of Python that will tell you:

If you’re on Windows, the easiest thing to do is add Django to your PythonPath environment variable. On Windows, you can define environment variables in the Control Panel. To do this, see Microsoft’s Command Line Reference for more details.

The excellent and well-written Django installation docs suggest creating a symbolic link to the file django-trunk/django/bin/django-admin.py in a directory on your system path, such as /usr/local/bin. I find that I don’t use django-admin.py all that often, but you can create the link if you like.

This is going to be our project folder into which we will add various apps. Some we’ll create and some we’ll be downloading as projects from Google Code. I like to keep my Python import statements clean and free of project-specific module names, so I always make sure my root project folder (in this case, djangoblog) is on my Python path. To do that, just add the path to your PythonPath variable.

That way we can write statements like:

import myapp

rather than

import myproject.myapp

It’s not a huge thing, but it does make your code more portable.

Fill out the project settings

OK, we’re getting there. The next step is to fill out our project settings file. Fire up your favorite text editor and open up the settings.py file inside the “djangoblog” directory.

The core of what we need to set up is at the top of the file. Look for these lines:

DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
DATABASE_NAME = '/path/to/djangoblog/djangoblog.db' # Or path to database file if using sqlite3.
DATABASE_USER = '' # Not used with sqlite3.
DATABASE_PASSWORD = '' # Not used with sqlite3.
DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.

Note that we’re using SQLite as a database for development purposes. Assuming you have Python 2.5 installed, you don’t need to do anything to use SQLite. If you’re on either Python 2.3 or Python 2.4, you’ll need pysqlite — make sure you install version 2.0.3 or higher. If you have MySQL or PostgreSQL already installed, feel free to use them.

Make Sure to include the entire pathname, as Django cannot understand ~/ or $HOME in defining the database ie /Users/usrname/Sites/dev/djangoblog/djangoblog.db

The other settings are well documented in the settings.py file and we can skip over most of them for now. But there are a couple of settings we should take care of before moving on. If you look at the bottom of the settings.py file you’ll notice this bit of code:

This where we tell our Django project which apps we want to install. In a minute, we’ll add our blog app. But for now let’s just add Django’s built-in admin tool. Paste in this line just below the sites app:

'django.contrib.admin',

One more thing before we finish with settings.py, here’s a handy trick for the template directories. I generally keep all my templates in a folder named “templates” within my project folder (in this case, “djangoblog”). But I generally move between development and live servers quite a bit and I hate having to change the path to the templates folder. This trick takes care of that:

Instead of hard coding the path to our templates folder this is dynamic — and it showcases how easy it is to tweak Django using Python. We just import the os.path Python module and then find the path to the directory where settings.py is and then appends ‘templates’ to that path.

Now when we push the site live, there’s no need to change the settings.py file. (Actually you’d probably want to switch to a more robust database, but we’ll get to that much later).

For now, let’s use one of the tools included in manage.py, the syncdb tool. Paste this line in your terminal:

python manage.py syncdb

The syncdb tool tells Django to translate all our installed apps’ models.py files into actual database table. In this case the only thing we have installed are some of the built-in Django tools, but fear not, we’ll get to writing our own models in just a minute.

Set up a user

Once you enter the syncdb line above, you’ll get some feedback from Django telling you you’ve just installed the auth system. It will walk you through setting up a user. The output looks like this:

Now that’s pretty cool. If you’ve ever labored over creating an admin system in Ruby on Rails or PHP, you’re going to love Django’s built-in admin system.

But at the moment there isn’t much to see in the admin system, so let’s get started building our blog.

Build the blog

Now we could just throw in some code that creates a date field, title, entry and other basics, but that wouldn’t be a very complete blog would it? What about tags? An RSS feed? A sitemap? Maybe some Markdown support for easier publishing?

Nice. But what about tags? Well there’s one of those apps available as well — the cleverly named django-tagging.

Now, there have been some backwards-incompatible changes to Django recently, and as of this writing, django-tagging hasn’t caught up to those yet. So we’re actually going to need to checkout the Newforms Admin branch of the django-tagging codebase.

To do that we’ll grab the files using Subversion. Paste this code into your terminal window:

Then just drop the tagging folder, which you’ll find inside django-tagging, in your “djangoblog” folder or wherever you’d like to keep it (I use a “lib” folder to hold all my frequently used components, like django-tagging).

There’s also a handy Python implementation of Markdown, so grab that as well (follow the setup instructions on the site to get Markdown installed). Markdown is entirely optional, so feel free to skip it if it’s not your thing.

Got all that stuff stashed in your “djangoblog” folder? Good.

Now let’s go ahead and create our first Django application.

To do that we’ll use Django’s app creating script, which lives inside manage.py in our project folder. Paste this line into your shell:

python manage.py startapp blog

If you look inside “djangoblog” you should now see a new “blog” folder. Open that up and find the models.py file. Open models.py in your favorite text editor and paste in this code:

Let’s step through the code line by line and we’ll talk about what’s going on.

First we import the basic stuff from django, including the model class, the Feed class and the Sitemap class.

Then we import the tagging and markdown files we just saved in our project folder.

Once we have all the modules we’re going to use, we can create our blog model. I elected to call it Entry — you can change that name if you like, but remember to substitute your name everywhere I refer to Entry.

Entry extends Django’s built-in model.Model class, which handles all the basic create read update and delete (CRUD) tasks. In other words, all we have to do is tell Django about the various elements of the database table (like the title field, the entry slug, et cetera) and all the hard work is handled behind the scenes.

The first bit of our Entry class definition just defines all our various blog entry components. Django will use this information to create our database tables and structure, and also to generate the Admin interface.

Note that we’re using Django’s various model fields. Most of it should be self-explanatory, but if you want to learn more about each type, check out the Django documentation. Also be aware that there are quite a few more field types available. This is only one example.

One thing worth mentioning is the body_html = models.TextField(blank=True) line. What’s up with that blank=True bit? Well that information is part of Django’s built-in Admin error checking.

Unless you tell it otherwise, all fields in your model will create NOT NULL columns in your database. To allow for null columns, we would just add null=True. But adding null=True only affects the database, Django’s Admin system would still complain that it needs the information. To get around that, we simply add the blank=True.

In this case, what we’re going to do is fill in the body_html field programatically — after we hit save in the Admin and before Django actually writes to the database. So, we need the Admin section to allow body_html to be blank, but not null.

Also worth mentioning is the Meta class. Meta handles things like how Django should order our entries and what the name of the class would be. By default, Django would refer to our class as “Entrys.” That offends my grammatical senses, so we’ll just explicitly tell Django the proper plural name of “entries.”

Next, we have a few function definitions. All Python objects should return their name. Django recently added unicode support, so we’ll return our name in unicode. Then there’s get_absolute_url. As you might imagine this refers to the entry’s permalink page.

When we get to creating templates, we’ll use this to put in our permalinks. That way if you ever decide to change your permalinks you only have to change one line and your entire site will update accordingly — very slick.

The last function simply overrides Django’s save function. Every Django model has a save function, and since we didn’t expose the body_html field, we need to fill it in. So we grab the text from our body_markdown field (which is exposed in the admin), run it through the markdown filter and store it in body_html.

By doing it this way, we can just call this field in our templates and we’ll get nicely formatted HTML as output, yet the process stays transparent — write in markdown, display HTML.

If you’re not using Markdown, just delete the save function, there’s no need to override it if you aren’t using the Markdown module.

Check your head

Now we need to tell Django about our new apps. Open up settings.py again and add these lines to your list of installed apps:

The first thing we do is import Django’s admin class, as you might suspect, admin controls how the admin interface looks. Now, these customizations are entirely optional. You could simply write pass and go with the default admin layout. However I’ve customized a few things and added some filters to the admin list view so we can sort and filter our entries. Note that if you aren’t using Markdown, just replace body_markdown with body_html.

We’ve also used a handy tool, Django’s prepopulated_fields, which will use a bit of Javascript to automatically build a slug from our title.

The last step is to register our admin customizations with Django’s admin app. If you aren’t actually making any customizations, you could just write the model name. In other words the admin class name is optional.

If you refresh your admin page you should now see the blog model with a link to create and edit blog entries.

Want more control over what shows up in your admin? For instance, if it’s a personal site, you probably don’t need the “Users” section in the admin. Let’s customize what shows up. To do that we’re going to create a new file, again named admin.py, but put this one at the project level, inside the djangoblog folder.

All this does is override Django’s default AdminSite and then simply registers our Entry model and admin classes. Of course you could do more than simply pass, check the Django docs for customization tips.

Now if you go back and refresh the admin page you should see just the things we’ve built — the Entries and Tags models.

Tweak the links and tags

One last thing, let’s jump back over to our models.py file; we’re going to add one extra function to our blog to improve its usability. Add these lines to the bottom of your models.py file:

Django includes a bunch of built-in methods for common tasks, like displaying next and previous links on pages. The function is called get_previous_by_ with the last bit of the function being the name of your datetime field, in our case pub_date. However, we included the ability to save drafts in our model, and, unfortunately, Django’s built-in function doesn’t know about our drafts. So, it will automatically include them in our next/previous links. This obviously isn’t what we want.

All this does is wrap the Django function with a new name get_next_published, call the original get_previous_by_ function, but add a filter so that only published entries are included in the results.

The last function in that set, get_tags, is just a time saver. There’s a good chance you’ll want to list all the tags you’ve added to your entry, so I’ve included a convenience method that does just that.

Onward and upward

Whew! That’s a lot of code to sort through, and we’ve glossed over a few things. But when you look at the models.py file and consider that from these 49 lines of code, Django was able to generate an entire blog website, it doesn’t seem like so much code at all, does it?

Save the file and head back over to your browser. Refresh the admin page and click “Add new.” Feel free to create a few entries — blog monkey blog!

So now we’ve got our back-end blogging system set up and everything in in place to create a public site. Feel free to take a well deserved break.