Grab the feed

School is a twelve-year jail sentence where bad habits are the only curriculum truly learned.

John Taylor Gatto

Recent comments

A Django deployment guide for Ubuntu

There's a time when every Django developer has to think about deployment scenarios, when I first did it last year I thought that a setup involving Lighty, Apache, mod_proxy and mod_python was a good choice but my first approach was not the best. I put Apache as the front server, handling requests for Django generated pages and passing, via mod_proxy, requests for static content to Lighty on the back. A setup where Apache had to work even for files that wasn't supposed to serve was a very bad idea.

After many helpful comments and some more reading I realized that it was better having the server for static content on the front and Apache, which still talks to Django, on the back.

I replaced Lighty with nginx, which according to many seems to be more stable, and opted for mod_wsgi instead of mod_python to make Apache talk to Django. mod_wsgi has a lower memory overhead and it's suitable for high performance sites. There's no need for mod_proxy on Apache anymore as nginx is the one in charge of the proxy work now.

This is an easy to follow and very focused guide for developers who know how to handle their servers so I won't consider security issues, memcached, Django installation, databases or basic GNU/Linux, Apache and DNS settings. Of course all of those subjects are important and you should take care of them.

The plan

This guide includes all the steps needed to:

  • Setup a domain for your Django project.
  • Create a simple directory layout for Django sites.
  • Configure Apache with mod_wsgi for Django.
  • Configure nginx.
  • Serve Django admin media files.
  • Turn on the heat and show your greatest and latest Django stuff to the world.

After following all the steps you will have a Django site running with nginx on the front and Apache on the back. nginx will manage all static content and will pass Django requests to Apache and mod_wsgi.

I have tested on three Ubuntu servers (two running 8.10, Intrepid Ibex, and one 7.10, Gutsy Gibbon) but everything should be pretty similar in other GNU/Linux distributions.

Shall we start?

Django questions and answers with a Swedish guy

Manolo Guerrero, that funny talking Mexican dude who happens to be a jQuery god and excellent friend of mine, introduced me to Andreas Krohn, a great pal from Sweden, evil mind behind WebHostNinja, with whom I've developed a nice Google App Engine and Django based Facebook application that will go live soon and I'll discuss later.

Andreas is a highly energetic online entrepreneur and developer who's considering Django for his next project and asked me a few questions about it. These were very good questions that many may have asked before and I thought my answers could help others getting used to the Django way of thinking.

How to use a public IP address with Google App Engine development server

And just when I thought that setting up Apache, mod_python and Lighty with Django was cool, and I haven't even started playing with mod_wsgi or nginx (the powerful Russian HTTP server, pronounced engine X) came the requirement to move the Django application I'm developing for Facebook to Google App Engine, the latest, and it seems the coolest, player in the cloud computing arena.

While my code was running on a pure Django environment I setup the callback url in Facebook's developer application to point to my local server, some simple port forwarding in my router did the trick. Now I wanted to do the same using Google App Engine's development server.

Regular expressions, Friedl and Kodos

Understanding and using the power of regular expressions, or simply regex, is a must for every smart programmer. Django uses them quite often on its elegant URLConf system.

I've been using regular expressions for a very long time and have read many books about them but if I have to recommend just one I'll go for the classic Mastering Regular Expressions by Jeffrey Friedl.

And nothing better to test you're on the right track while writing your own regular expressions than Kodos, a simple but nice Python based tool, easy to install from any Debian based distro with a quick sudo apt-get install kodos.

Use double quotes for {% url %} on Django

I recently commented about using the right quotes with Python and simplejson and today I found a similar issue with Django.

It happens when using the {% url %} tag on the template system in Django 1.0. {% url %} helps you to avoid hardcoding links and relies on naming your url patterns.

Let's suppose we have a url like this in our URLConf:

url(r'^add/chatroom/(?P\w+)$', 'myapp_chatroom_add', name='myapp_chatroom_add'),

Now you could insert {% url %} in your template to get the url for a link:

{% url myapp_chatroom_add chatroom_data="abc" %}

Notice I'm passing the string "abc" using double quotes as the chatroom_data parameter.

And here's the important part, these two won't work:

{% url myapp_chatroom_add chatroom_data=abc %}

which does not use quotes at all, or this one:

{% url myapp_chatroom_add chatroom_data='abc' %}

which uses single quotes.

The errors may vary depending on how your code works but the fact is to remember that when passing string based parameters to {% url %} you need to always use double quotes.

If you're using numbers you could use either no quotes or double quotes. Single quotes will never work.

How to setup Apache, mod_python and a reverse proxy to Lighttpd for Django on Ubuntu

I'll Django for food

Update: I don't recommend this setup anymore. Use the improved setup of Django with nginx, Apache and mod_wsgi.

It's October 2008 and there's no doubt now that serious web development requires working with frameworks, software that allows us, lazy coders, to forget about repetitive tasks and focus on the specifics of each project, the stuff that makes them truly unique.

It's pretty obvious too that Django, the Python based web framework, is attracting more developers and companies lately. Guido is a googler since 2005 and the recently launched Google App Engine uses Python and Django. Seriously, there's not a better time to jump into the Django train (no pun intended RoR guys).

Experienced programmers can start writing Django applications quickly thanks to the excellent documentation and the free Django book. I've also read and can recommend Practical Django Projects, by James Bennett, part of the Django team, and Learning Website Development with Django, by Ayman Hourieh, a very smart and young Google engineer.

Django is really a web framework for perfectionists with deadlines. I'm very near to one and have almost finished coding what will be my first Django based application for Facebook. Yes, I've got a few articles about that coming soon as well.

So, everything looks great under the Sun on Djangoland? Well, there's something that bothered me since I started a few months ago: deployment on a production environment. The documentation and most books get us up and running quickly with the included development server and then just refer us to the recommended Apache and mod_python settings for more.

Unfortunately, specially if you're used to the common Linux, Apache, MySQL and PHP setup, like I was, you may be need more detailed instructions and that's why I decided to write this tutorial on how to setup Apache, mod_python and a reverse proxy to Lighttpd for Django.

Passing variables to named patterns via {% url %} in Django templates

When coding Django one of my most important goals is avoiding all kind of hardcoded urls in my applications. Let's see this line from one of my app's URLConf:

url(r'^edit/object/(?P<object_id>\w+)/$', 'object_edit', name='object_edit'),

This points to a page like /edit/object/123, notice I'm using a named pattern here, and calls a view defined with:

def object_edit(request, object_id):

Then I can do what I need with the object identified by object_id.

Now, imagine I have a list of objects in a template so I can add an edit link to each one of them, something like this:

<a href="{% url object_edit object_id=4}">edit object</a>

Notice that 4? I put it there just for making my point clear, what I really want to do is something like:

<a href="{% url object_edit object_id={{ object.object_id }} %}">edit object</a>

but that produces an error like this: TemplateSyntaxError at ... Could not parse the remainder: '{{' from '{{'.

It seems a template variable can't be used inside a {% url %} tag, and I guess the same applies to any template tag. After thinking a bit about how other tags work with variables, the {% for %} loop for example, I decided to get rid of the {{ and }}:

<a href="{% url object_edit object_id=object.object_id %}">edit object</a>

And yep, that worked. I hope this helps anybody else having a similar question.

PYTHONPATH and configuring Django with Apache and mod_python

One more post about my experience coding a Django application for Facebook. Let's discuss a little about correctly setting up Apache and mod_python.

Most of the steps are very well described on Django's documentation but you may need a few more details. Let's see.

HTTP 200 testing Django applications with Facebook

I've been writing a simple Django application for Facebook these days. I'm really enjoying how clean Django's code is and its very well thought classes and methods. It really makes web development faster.

I started with some simple HTML running locally on Django's development server and then updated my templates to output FBML based on the value of a variable I called IN_FACEBOOK and inserted into my settings.py.

After adding PyFacebook to talk to Facebook's API from Python I configured my new application according to Facebook's instructions.

Finally I changed my router's port forwarding settings to allow Facebook to see my home server's public IP, which is dynamic and provided by my ISP.

Everything ran ok up to this point and then I started noticing that after each change on my application's code Facebook returned a blank page with an HTTP 200 message.

It seemed like a connection issue and I moved the application to my real server, which has a fixed public IP, but the problem persisted. After every code change Facebook returned a blank page with the HTTP 200 message. I needed to refresh the browser three or more times to get my application loading.

My application is still on development but even so I decided to replace Django's server with an Apache and mod_python setup.

Presto¡ That was the source of the problem. It seems Django's development server response time is too high for Facebook.