Step 1: Disinterring and Reviving To Life

I shelved/buried my blog when I upgraded to a new slicehost linode six years ago. I didn't have it on github or gitlab, or on my personal dev machine, and it seemed to be completely purged from my little server. My last hope was the tarball labelled fullbackup.tar.gz in the home dir of the server. Oh, but by the way, my server was out of disk space and I was doing all this while on vacation in rural Nova Scotia, where high speed Internet is still a far-away dream.

Read on for how I unseized my old server, recovered my old blog code and data, and finally got it up and running.




This Is An Old Blog

This blog started in the winter of 2008. I'd been in the industry for a few years and Django had reached 1.0. I figured it was time to make myself a blog, knowing, even then, that it was completely unnecessary. I just wanted the practice.

My last post (something not-that-great about Christmas) was, until now, from December 2012.

Anyway, a lot has changed in the software world. I've also caught up with a few things I wish I'd known 10 years ago.

So, lacking anything else to write about. I'm going to try and refurbish this blog and write about that.

Here's just a few of the things to address:




Like QuerySets, but crazier

I have a crazy QuerySet idea.

Imagine we have this:

class Task(models.Model):
foo = models.CharField()
class TaskStatus(models.Model):
task = models.ForeignKey(Task)
user = models.ForeignKey('auth.User')
status = models.CharField(default='not-done')
class Meta:
unique_together = ('task', 'user')

Now imagine we're listing Task.objects.all() on a page. We need to show the user's status for each task, so we do something like this:

b_list = []
for a in A.objects.all():

That sucks because it's doing an extra db query for each object. We can work around that problem, but this also sucks because we're sort of needlessly creating new records when we don't need them. If the TaskStatus is being created with a default status, and we know that's what it will be because we're creating it, couldn't we just assume that status if there's no TaskStatus object and skip the creation? Yes, we could probably do that too. But now our code's going to look a little messier. I won't both writing it out, but you can imagine, right?

Here's my crazy idea:

Write a manager method that returns a custom QuerySet subclass that will do something like this internally:

    def get_for_user(self, user);
tasks = Task.objects.all()
task_status = dict([(, ts) for ts in self.get_query_set().filter(user=user)])
for task in tasks:
if in task_status:
task = task_status[]
task = TaskStatus(task=task, user=user))
yield task

But, you know, done up so it behaved like a queryset instead of a plain iterator, where you could filter, exclude, get, etc.. So what you get is a queryset that includes all the objects you would normally find from the db, plus some freshly created (and un-saved) objects.

It seems like something like this could let you avoid a lot of db hits and extra db entries and would be transparent to the code that was using it.

Implementing this for general use would require some deep Query fiddling, but I think it could be manageable if I wrote it for this one application instead.

So crazy it might work, or is it the wrong amount of craziness?



URLs on multi-lingual sites: A solution

Let me tell you about two problems:

  1. Your site is localized into multiple languages, but the words in its URLs can only be in one language. For example, "/products/" isn't a great URL if you can't read English.

  2. Django's language switching is kind of crappy. You have to post to a view to change the language, and it's hard to expose all the site's translations to search engines for indexing.

Ladies and gentlemen, the solution is at hand: Transurlvania!




A Noob In King Guido's Court

Here I am, somehow, impossibly, in Chicago and attending PyCon.

Somewhere in this crowd are other Djangonauts. I need to figure out how to find them.



Software Design Paralysis

Friends, I have come to an impasse.

There's a reason why I still don't have image embedding up on the site. Read on and help me!




Markdown w/ Pygments: Round 2

Dig back into my vast blog archive and you will find this post: I said it, I did it. Therein you will find my bumbling, ham-fisted solution for integrating pygment code highlighting into markdown.

I just wandered back past this code today and then stumbled across the actual right way to do this.





Anyone attempting to dip into my modest archive this morning would have seen an error message instead.

I discovered a bug in how my archive_month view was working and I fixed it. And in the process I opened a much worse bug. This is one of the classic narratives, along with "boy meets girl", "stranger comes to town" and the rest.

Let me tell you all about it...




Private Posts and Custom Managers

I have all these cool ideas for how this blog is going to knock the socks off of sliced bread, or at least, all things since sliced bread. But to get there, I keep stumbling over all this pesky functionality I don't have.

In a way it's one big lesson in project management. All the little, round-down-to-zero-time tasks add up to an alarmingly non-zero number.

Today's addition is a public checkbox on the BlogPost object. That, plus the custom manager that goes with it. Plus the updates to the views. Plus the test to make sure it works. Plus the Django Evolution code.

Read on for more! I've got some racy opinions on custom managers in here that you won't want to miss!




Cue The Sun

This is my post for showing off how the sun gets rendered during evening twilight. I am tweaking the publish date a bit because I -ahem- forgot to post this a little earlier.



Hickory Dickory Dock...

This is the nerdiest, least useful thing I've added to this site so far: an analog clock renderer!

Check it out: you get a regular clock with an hour hand and a minute hand, but you also get a sun indicator, to help you tell AM from PM. When it's daylight, the sun travels through the sky in nice happy yellow. When it's night time the sun travels around the lower half of the circle and gets drawn a dark blue. The extra fun part is that if it's near sunrise or sunset, the sun's colour is drawn from a gradient between the noon-day yellow and a bright red. I'll have to make a point of posting at dusk tomorrow.

I have no idea if this technique for representing time is at all intuitive, but I really enjoyed making it.




Free Previews

My friends, I have something exciting (and completely unnecessary) in the works.

To pave the way for all the stuff I want to say about that, I've added previewing to my blog.

Let me tell you all about it, below the fold.




Darwin Rears His Head

I'm using Django Evolution with this project because I knew I would need to muck with my models at some point. Ladies and gentlemen, that point has come!

In order to get categories set up I had to add a foreign key to the Category model from my BlogPost model. I've used the "./ --hint" → "./ --hint --execute" pattern before in other projects, but I decided to use Django Evolution's "Stored Evolutions" feature this time. It turned out to be painless, and I think i could smell rose petals and the absence of stress.

  • I ran ./ --hint

  • I copied the lines between the "---------" bits into a file inside blog/evolutions. That looks like this:

from django_evolution.mutations import *
from django.db import models
AddField('BlogPost', 'category', models.ForeignKey, null=True, related_model='blog.Category')

I also created a file in there.

  • I added this line to the __init__ file:

SEQUENCE = ['add_category_fk']

  • I got all my changes checked in, pushed the code up to my slice and ran ./ evolve.
    Django Evolution found the evolution file, warned me that it might destroy my data or blot out the sun if I let it run, and then executed the evolution perfectly.

This is a simple case, I know, but this was still a lot easier than firing up psql. A tool that only helps with the easy 80% of the cases is still a useful tool, I think.



Category: Not Dead

Good evening, world!

I have been wracked by horrible guilt this past week, knowing that my new, youthful blog was lying fallow.

Here I am, making amends!

I've added categories to my blog. I now have the ability to separate my developer nonsense from my "personal" nonsense. (Note: "Personal" here is used not to mean "private" but rather, "less interesting to others".) I've also added category-based news feeds. Just go to the category page and subscribe to the feed from there.

Adding categories required new code in a bunch of places. It's not all very interesting. I split my blog post list displaying template code out into a sub-template called "_blogpost_list.html", because I'm using it in a few different templates now, but the code's basically the same.

I did create two new template tags. One is the archive nav code I had earlier, refactored:

def archive_nav(month=None, category=None):
queryset = BlogPost.objects.all()
if category:
queryset = queryset.filter(category=category)
return {'category': category,
'active_month': month,
'month_list': queryset.dates('pub_date', 'month')[::-1]

With the new archive nav code, I'm giving up on using the date_list object that the date-based generic views provide. date_list only lists the years that contain content. I was using a little template filter that would take a date representing a year, and return a list of all months with content in that year. It worked great when I always wanted to examine all the content, but it became a nuisance when I sometimes wanted to restrict it to only those blog posts that were in a certain category. I could have fiddled some more with the filter but I decided it would be tidier to write a complete template tag instead and leave date_list behind.

Here's the template:

<ul class="nav-bar">
<li>Archive: </li>
{% for month_date in month_list %}
<li{% ifequal active_month %} class="active"{% endifequal %}>
{% with month_date|date:"F" as month_str %}
{% if category %}
<a href="{% url category_archive_month category_slug=category.slug,year=month_date.year,month=month_str.lower %}">
{{ month_str }} {{ month_date.year }}
{% else %}
<a href="{% url blog_archive_month year=month_date.year,month=month_str.lower %}">
{{ month_str }} {{ month_date.year }}
{% endif %}
{% endwith %}
{% endfor %}

I discovered something new when I was updating my other templates to use archive_nav properly: Django templates don't support the "None" keyword. When I'm loading the archive nav inside the category detail page I need to pass the category, but I don't have an active month to pass. Here's what I settled on:

{% archive_nav "" category %}

It seems like there ought to be a nicer way to do this, but keyword arguments don't work with simple or inclusion tags and I can't use None.

Anyway, at the end of the day, we're left with an exciting new feature that every other blog already had without even thinking about it. I've got some great ideas on rotating, circular vehicle conveyance tools, as well.



Your comments are appreciated

I was gearing up to lay down some TDD on a simple comment e-mailing tool. Then, as I was flipping open the Django source to check something, I noticed a "feeds" module in the comments app. I aspire to Larry Wall's [three cardinal virtues of the programmer] ( and a news feed of comments sounds at least as useful as a comment e-mailer, and it had the virtue of already existing, right there in Django.

Ah, but then I noticed: What comments gives you is an RSS news feed. Ahem. I'm cultivating a refined sense of snobbery and hating on MySQL is only the beginning. It has to be Atom or nothing. Don't worry; this time I kept things pretty DRY:

class LatestCommentsAtomFeed(LatestCommentFeed):
def subtitle(self):
return self.description()
feed_type = Atom1Feed
def item_author_name(self, item):

All I did was set the feed type and make the subtitle field stand in for the description field. And hey, I figured since we have a name field in the comment, we may as well use it as the author name for each item. I expect there's some obvious reason why I wouldn't want to do this, but in my minimal, unscientific testing with Net News Wire, it seems to work fine.

I don't know where to embed a link to something of as questionable interest as a comments-only news feed. Well, maybe I do. Here you go.



Flat, But Smart

I just wanted to note something neat.

When I was setting up my flatpage template last night I realized I could run template filters on the two strings, flatpage,title and flatpage.content. So now, instead of having to embed raw HTML in my flatpage entry like a brutish savage, I can enter pure, clean-burning markdown and just pipe it through the parser in the template.

Here's the flatpages/default.html template:

{% extends "base.html" %}
{% load markup %}
{% block title %}{{ block.super }} - {{ flatpage.title }}{% endblock %}
{% block content %}
<h1>{{ flatpage.title }}</h1>
{{ flatpage.content|markdown }}
{% endblock %}

Funny side note: I actually felt shamed into editing this template to conform to Eric Holscher's Gentleman's Agreemant on Django Templates



Submitted without comment, no longer!

Hey, y'all.

As soon as I got home today i set to work getting commenting working. And sure enough, a mere four hours later, here we are! I haven't changed much from the out-of-the-box django commenting solution, so I'm hoping it just purrs along.

I also added an about page so you can learn some unhelpful trivia about me. Click on my name to get there.



The Florenzano Factor

Eric Florenzano (A Django Wizard) has instigated a meme (Update: Now with URL back to his post. Guh. I'm a yutz.):


  1. Implement a program that takes in a user's name and their age, and prints hello to them once for every year that they have been alive.
  2. Post these rules, the source code for your solution, and the following list (with you included) on your blog.
  3. Bonus points if you implement it in a language not yet seen on the following list!

The List:

  1. [Python]
  2. [Bash]
  3. [C]
  4. [Java]
  5. [Python 3]
  6. [Ruby]
  7. [Ruby]
  8. [Lisp]
  9. [JavaScript]
  10. [Django]

Yes, friends, that's right. I did it in Django. But not only that, I did it in one file in Django.

Dig it:

{# #} {% comment %}
from django import forms
from django.conf.urls.defaults import *
from django.http import HttpResponse
from django.template.loader import render_to_string
DEBUG = True
DATABASE_NAME = ':memory:'
ROOT_URLCONF = 'settings'
class NameAgeForm(forms.Form):
name = forms.CharField()
age = forms.IntegerField()
def view(request):
if 'name' in request.GET:
form = NameAgeForm(request.GET)
if form.is_valid():
name = form.cleaned_data['name']
ages = range(1, form.cleaned_data['age'] + 1)
form = NameAgeForm()
return HttpResponse(render_to_string('', locals()))
urlpatterns = patterns('',
(r'^$', view),

# {% endcomment %} <html><head><title>The Age Machine</title></head><body>{% if name and ages %} {% comment %}
# {% endcomment %} <ul>{% for age in ages %}<li>{{ age }} - Hello {{ name }}</li>{% endfor %}</ul> {% comment %}
# {% endcomment %} <form action="/"><input type="submit" value="Reset" /></form> {% comment %}
# {% endcomment %} {% else %}<form method="GET" action="/">{{ form.as_p }}<input type="submit" /></form> {% endif %}</body></html>

To run it, just put this code in a file called and run: runserver --settings="settings"

I managed to get everything crammed into the settings file, and then I made the settings file double as the template. You're either going to be really impressed or really angry. Let me know, either way.

sam - at -



Yes, I know

The source code in the last post is probably too wide for your browser window and the blog post window isn't expanding properly. And, if you have a horizontal scroll bar and use it, you'll see the blog post design disconnect from the background. (Update: Fixed. I told the pre elements to apply scroll bars to text not content to be bound by the requirements of reasonable width.)

Not pretty.

It looks like I'll have to make this a tiling, scrolling background after all. Boo.

This is why it's better to have other people around who can take care of all this HTML and CSS.



These Are the Months Of Our Lives

Behold! An update!

I've just added month-based archiving. It's just another wrapper around a generic view. I did write a couple template tags to help build my list of archive links the way I wanted to. I wanted to present a flat list of months with posts in them, leaving out the year-archive pages entirely.

Here's the template code I wrote to present the list of archive month links on the home page:

<ul class="nav-bar">
<li>Archive: </li>
{% for d in date_list|months_with_content %}
{% with d|date:"F" as m %}
<li><a href="{% url blog_archive_month year=d.year,month=m.lower %}">{{ m }} {{ d.year }}</a></li>
{% endwith %}
{% endfor %}

For the month archive template I wrote a different block of code to link to list the current month and the months on either side, since that's what the archive_month view affords me

<ul class="nav-bar">
<li>Archive: </li>
{% if previous_month|has_posts_in_month %}
{% with previous_month|date:"F" as month_str %}
<li><a href="{% url blog_archive_month year=previous_month.year,month=month_str.lower %}">{{ month_str }} {{ previous_month.year }}</a></li>
{% endwith %}
{% endif %}
{% with month|date:"F" as month_str %}
<li><a class="active" href="{% url blog_archive_month year=month.year,month=month_str.lower %}">{{ month_str }} {{ month.year }}</a></li>
{% endwith %}
{% if next_month|has_posts_in_month %}
{% with next_month|date:"F" as month_str %}
<li><a href="{% url blog_archive_month year=next_month.year,month=month_str.lower %}">{{ month_str }} {{ next_month.year }}</a></li>
{% endwith %}
{% endif %}

And finally, here are the two template tags I wrote that are used in that template code:

def months_with_content(date_list):
Returns a list of months where there are blog posts within the year range
{{ date_list|months_with_content }}
dates = []
for year_date in date_list:
dates += list(BlogPost.objects.filter(pub_dateyear=year_date.year).dates('pub_date', 'month'))
return dates

def has_posts_in_month(date):
if not date:
return False
return BlogPost.objects.filter(pub_date
year=date.year, pub_date__month=date.month).count() > 0

Can you tell I'm a back-end programmer from that beastly Django templating?



Your Ever-bloggin' Man

I changed something else on the site just now, but you can't see it. I changed the home page view to wrap the date-based archive_index view instead of just direct_to_template.

So now, when I write my 16th news post, the first post will slide out of view on the home page. And if I get sneaky and write any posts dated into the future, they'll stay tucked away until the appointed date and time.

Here's how my home view looks now:

def home(request):
return date_based.archive_index(

And clever (for once) me, I remembered to run my tests and discovered that two no longer worked because I'd changed the name of the list of blog posts. That's fixed and all tests are passing. I haven't added any tests to confirm that archive_index is doing its special thing, though. That's bad. I should add a couple tests tomorrow. It's too late to be TDD, but it would be something.



I Have The Power!

As you can now see, this site is brought to you courtesy of magical ponies.

In the end (once I get categories implemented) I don't think Django is going to be the only thing I discuss here, but it's what I do all day, and it's what I'm using to build this whole ramshackle thing. And believe me, you're all better off with this limitation. Sooner or later I'll start blathering about my cute kitty-cat or housework and nobody really needs that.

So, for now, welcome to my Django blog!



A Bridge Too Far: Simple Redirects

No new work on the blog today. Boo.

Unless you count spending half an hour trying again to get to redirect to Django only does the redirect when it's in the mood, so I tried adding an Apache rule. Thus enters (dramatic music) mod_rewrite, slinking its way in, complicating the simple, and confounding the brilliant.

This is in my virtual host for (with a ServerAlias to Does it make any sense? (contact email = my first name at this domain name)

  RewriteCond %{HTTP_HOST}   !^ [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*)$1 [L,R]

Oh yeah. I did get one other thing set up: Google Analytics. It's set to track traffic to, so I should see at least some of you guys as you come in.

I got it working. You know what helped?

  RewriteEngine on



Feed Me Seymour

In response to a flood of calls, telegrams and carrier pigeons, I have given in and implemented an Atom news feed for these posts. As a side effect, I've also implemented a blog post detail view.

Still to come: categories, comments, and pagination. For now, check out my date-based object_detail wrapper view.

def post_detail(request, year, month, day, slug):
return date_based.object_detail(
month=month, month_format="%B",
slug=slug, slug_field='slug',

At this point I could have just as easily used the generic view directly, but some of my fellow Django nerds have picked up two funny habits with views:

  1. Never use generic views directly
  2. Always use them indirectly.

That is, even if your view doesn't add anything you should still create it and call the generic view from inside instead of by using the generic view directly and passing a dict in the url conf. And even if your view does a whole bunch of stuff that's not at all covered by the generic view, you should still ultimately let some generic view generate the response. If nothing else, just use simple.direct_to_template and pass in your context.

The shortest explanation for why this makes sense is: we don't like business logic in our url confs, and we don't like having to construct RequestContext objects all the time. Beyond that, it's more hazy. To be honest, I'm still mostly giving it a test drive to see if my friends are crazy or not.



I said it, I did it.

I got syntax highlight working. I didn't do it during the same calendar day as when I said I'd do it, but everyone knows that your day can't actually end until you go to sleep. I'm currently in 2 hours of overtime on the 21st of November.

I figured this would be a little tricky, but I was honestly surprised that the solutions people had described in their blogs and on djangosnippets were so... complicated. Pygments as a markdown pre-processor. Ideally one would be able to just pass this through as an extension to markdown using the functionality in the existing template tag. Unfortunately, pre-processors seem to be a different sort of animal. In the end I couldn't keep things very DRY. I had to copy and alter the markdown template filter (I trimmed out a lot of the backwards compatibility stuff because I knew what version of markdown I'd be using), and (even worse), I had to copy and alter the actual markdown function.

Here's the code that I copied and modified. The only other things I needed to get this going were Pygments itself and a bunch of illegible css rules that Pygments generated for me. This is the "manni" colouring style, by the way.

from django import template
from django.conf import settings
from django.utils.encoding import smart_str, force_unicode
from django.utils.safestring import mark_safe
from markdown import Markdown
from pg_md_processor import CodeBlockPreprocessor
register = template.Library()
def markdown(value, arg=''):
Runs Markdown over a given value, optionally using various
extensions python-markdown supports.
{{ value|markdown:"extension1_name,extension2_name..." }}
To enable safe mode, which strips raw HTML and only returns HTML
generated by actual Markdown syntax, pass "safe" as the first
extension in the list.
If the version of Markdown in use does not support extensions,
they will be silently ignored.
extensions = [e for e in arg.split(",") if e]
if len(extensions) > 0 and extensions[0] == "safe":
extensions = extensions[1:]
safe_mode = True
safe_mode = False
return mark_safe(_pygmented_markdown(force_unicode(value), extensions, safe_mode=safe_mode))
markdown.is_safe = True
def _pygmented_markdown(text,
extensions = [],
safe_mode = False):
extension_names = []
extension_configs = {}
for ext in extensions:
pos = ext.find("(")
if pos == -1:
name = ext[:pos]
pairs = [x.split("=") for x in ext[pos+1:-1].split(",")]
configs = [(x.strip(), y.strip()) for (x, y) in pairs]
extension_configs[name] = configs
md = Markdown(extensions=extension_names,
safe_mode = safe_mode)
md.textPreprocessors.insert(0, CodeBlockPreprocessor())
return md.convert(text)

Other than stripping out all the compatibility stuff in the template filter, the only change there is from "markdown.markdown" to "_pygmented_markdown". And in _pygmented_markdown, I'm just adding one line towards the bottom:

md.textPreprocessors.insert(0, CodeBlockPreprocessor())

Seems like there ought to be a tidier way to do this.

Commenting should be set up soon. If you need to reach me. My email address is my first name "at" this blog's domain.



Django: First Blood

I realized that markdown will still nicely display code blocks even if there's no fancy syntax colouring (Update: I've got syntax highlighting now. Dig it!), so I thought I'd post the little bit of code I've already written. You may or may not be surprised by just how little I've written to make this thing go. I only have one app, "blog", with one view, and one template. Here's the model:

class BlogPost(models.Model):
"""A simple blog post"""
title = models.CharField(('title'), max_length=100)
slug = models.SlugField(
('slug'), max_length=100, unique_for_date='pub_date')
pub_date = models.DateTimeField(('pub_date'),
body = models.TextField(
('body'), blank=True)
class Meta:
verbose_name = ('blog post')
verbose_name_plural =
('blog posts')
ordering = ('-pub_date',)
def unicode(self):
return _('%(title)s (Posted: %(pub_date)s)') % {
'title': self.title,
'pub_date': self.pub_date.strftime('%B %d, %Y')

I'm trying to stick to Test Driven Development with this project. Here are the tests I've written. The code that makes these tests pass is so boring I won't even post it.

class HomePageTestCase(TestCase):
fixtures = ['test.json']
def setUp(self):
self.client = client.Client()
def testHomePageLoads(self):
response = self.client.get('/')
self.assertEqual(response.status_code, 200)
def testBlogHomeTemplateUsed(self):
response = self.client.get('/')
self.assertTemplateUsed(response, 'blog/home.html')
def testBlogListInContext(self):
response = self.client.get('/')
self.assertTrue('blogpost_list' in response.context[0])
def testBlogPostInResponse(self):
response = self.client.get('/')
self.assertTrue(len(response.context[0]['blogpost_list']) > 0)
blog_post = response.context[0]['blogpost_list'][0]
self.assertContains(response, blog_post.title)



Today: The Plan

Today I plan to wield my mighty hammer of Django-making and meet my commitments at work. We're trying to follow an agile process now, which means we can all very precisely track how much I do or don't get done in a week.

I also plan to steal some time to add support for syntax highlighting in this blog. I'd like to post bits of the code that I've written to power this blog. This is to fulfill some of the meta/navel-gazing requirements.