Django for the Impatient: The Finishing Touches / Page 2

Django for the Impatient: The Finishing Touches [con't]

Finishing Touches

Using the key concepts laid out so far, you could go forward and refine this primitive blog engine in a number of ways. Let's step through a few of them to make this project feel just a little more polished.

Template Niceties

Our template is plain to say the least. Because this is a book on Web programming not Web design, we leave the aesthetic touches to you, but template inheritance is another feature of the template system that can make your life easier, especially as your page styles proliferate.

Our simple template is completely self-contained. But what if our site had a blog, a photo archive, and a links page, and we wanted all these to be based on a common base? Experience tells you the wrong way to do this would be to copy and paste your way to three kind-of-identical self-contained templates. The right way in Django is to create a base template, and then extend this template to generate the other, specific templates. In your mysite/blog/templates directory, create a template called base.html containing the following:

Not exactly valid XHTML Strict, but it'll do. The detail to notice is the {% block ... %} tag.This defines a named area that subtemplates can change. To make your blog app use this template, change your archive.html template so it references this new base template and its "content" block.

The {% extends ... %} tag tells Django to look for a template named base.html, and plug the content of any named blocks in this template into the corresponding blocks in that template. You should now see something like Figure 2.10 (hopefully your blog posts are more exciting, though).

Date-Based Ordering

You should have noticed your blog posts are not being presented in traditional reverse-chronological order. It's easy for us to tell Django to do that; in fact, we have a choice as to where we want to tell it to do so. We can add a default ordering to our model, or we can add it to the BlogPost.objects.all() query in our view code. In this case the model is a better location because we most often want posts ordered reverse chronologically. If we set our preferred ordering in the model, any part of Django that accesses our data uses that ordering.

To set default ordering for your model, give it an inner class called Meta and set the ordering attribute in that class.

Take a look at your blog home page (/blog/). The newest post should now be on top. The string -timestamp is a concise way of telling Django, "order by the 'timestamp'field, and do it in descending order." (If we omitted the "-", they'd be presented in ascending date order instead.)

Note; Don't omit the trailing comma inside the parentheses! It makes this a single-item tuple, rather than just a parenthesized string. Django expects a tuple here; you're allowed to specify as many fields for ordering as you want. If you added 'title' after the comma, and you had two posts titled "A" and "B" with the same timestamp, post "A" would come first.

Timestamp Formatting Via a Template Filter

That timestamp is handy, but its ISO8601 format is a little nerdy. Let's humanize it a bit by using a cool feature of the Django template system: filters.

Because this is a presentation detail, not a data structure or business logic detail, the appropriate place for it is in the template. Open your archive.html file and change the "post.timestamp" line to

To apply a filter to a variable, you simply tack it on to the end of the variable name— inside the curly brackets—using a vertical bar, or "pipe," character. Reload your blog home page. Now your dates appear in a more liberal-arts-friendly form ("July 7 ").

If the default style of the date filter isn't to your liking, you can pass it an argument using strftime-type formatting. However, rather than using the conversion codes from Python's time module, it uses the same formatting directives as PHP's date function. For example, if you want to display the day of the week but omit the year, change the line to pass an argument to the date filter.

This particular format string gives you dates in the style "Friday, July 6th." Make sure you don't leave any space on either side of that colon—the Django template engine is particular about this.

Summary

Of course, we could continue adding features to our blog engine forever (many people do!), but hopefully you've seen enough to give you a taste of the power of Django. In the course of building this skeletal blog app you've seen a number of Django's elegant, laborsaving features:

The built-in Web server, which makes your development work more self-contained and automatically reloads your code if you edit it

The pure-Python approach to data model creation, which saves you from having to write or maintain SQL code or XML description files

The automatic admin application, which provides full-fledged content-editing features even for nontechnical users

The template system, which can be used to produce HTML, CSS, JavaScript, or any textual output format

Template filters, which can alter the presentation of your data (such as dates) with out messing with your application's business logic

The URLconf system, which gives you great flexibility in URL design while keeping application-specific portions of URLs in the application, where they belong

You've completed your whirlwind tour of Django basics. Chapter 3, fleshes out with a broad look at Django's key components and the philosophies behind them, as well as provides a recap of some Web development principles central not only to Django itself, but to the lessons we offer in later parts of the book. Chapter 4, takes you down into the details of the framework, where you find answers to the questions of "how, why, and what about ...?" that probably arose as you walked through the previous examples. After Chapter 4, you have a solid enough understanding to follow along and build several example applications: a content management system, a pastebin, a photo gallery, and an Ajax-powered "live blog."