Django, paths and URLs

December 22, 2007

Michael Trier has a blog post on how he keeps his Django projects portable from one directory to another. This is something that gave us a hard time at work too and that we managed to fix (differently.)

To give you a brief idea of what we do, we usually develop small web sites for small companies. Because of the pains of using PHP, we moved all our new development to Django and have been satisfied. There are some areas that have caused us trouble however, and the number one pain is deployment. Some things are out of our hands, such as restarting Apache when a Python file is modified. But having to change a bunch of directories and URLs whenever we deployed, that was way too annoying not to be fixed.

We have a basic Django project skeleton that we now use whenever we start a new site. It is called WSF (short for “WebSite Framework”.) Before we had WSF, we started ever new project with the startproject command, and did everything anew over and over. The really sucky part was that between my designer and me, code would sometimes break because we did not keep our working copy in directories with the same names. And with the demos and the production servers having different directory names, it was evident that we needed to do something about that.

Our web sites usually go through four different file system paths:

  • My working copy
  • The working copy of my designer
  • Our demo server
  • The production server

We also needed our projects to work with different base URLs:

  • Development URLs (directly at the root)
  • Demo URLs (under /demos/client/wsf/)
  • Production URLs (under /wsf/ for technical reasons)

Paths

The first problem we concentrated on were the file system paths. Because the settings file in Django is a Python script, it was possible to use the path manipulation libraries to achieve portability. There are two paths you want to set in the settings.py module: MEDIA_ROOT and TEMPLATE_DIRS.

By using os.path, it was possible to set the correct paths dynamically:


PROJECT_PATH = os.path.dirname(os.path.abspath(__file__))

MEDIA_ROOT = os.path.join(PROJECT_PATH, 'media')

TEMPLATE_DIRS = (
    os.path.join(PROJECT_PATH, 'templates'),
)

The magic __file__ variable is the name of current module, in this case, settings.py. We use abspath to get the complete path, and we truncate the file name with dirname. This fixed all our path related problems, it was now easy to move the application between different folders.

URLs

Our next problem were the URLs. When we developed on our own machine with the built-in development server, the URLs were simply http://server:9090/foo/. When we moved the project to the demo server (served by Apache), the base URL was http://demoserver/demos/client-domain.com/wsf/. The reason for the trailing /wsf/ is that all of our projects have the name wsf, so for the import statement to work in Python, the folder needs to be named wsf too. We use .htaccess files to tell Apache to server the directory as a Django application.

We fixed the changing URL problem by defining a variable in the settings file called BASE_URL. In development mode, this would be set to the empty string, and on the demo server, we’d change it to ‘demos/client-domain.com/wsf/’.

Our urls.py file used this setting:


from django.conf.urls.defaults import *
from django.conf import settings

urlpatterns = patterns(
    '',
    (r'^%s' % settings.BASE_URL, include('wsf.site.urls')),
)

And in the site/urls.py file, the URLs were defined normally. By using the {% url %} tag in the templates and the reverse() function in the Python code, our URLs were portable…

But not all of them. There was no way to use {% url %} with the media files. We fixed this problem with a filter:


from django.conf import settings

@register.filter
def media(file):
    '''
    Concatenate MEDIA_URL and file.
    '''

    return settings.BASE_URL + file

So whenever we need to display a media file, we do the following:


<img src="{{ "images/foo.jpg"|media }}" />

and the correct URL will be used. We also use this filter in our CSS files (they are not served statically) for when we use the url() command.

Conclusion

With these simple settings, when we move an application from development to the demo or the production server, we need only change the BASE_URL setting and the rest of the project will work as expected.

I would say that this whole path and URL thing needs to have a better engineered solution before 1.0 is released. With PHP, it’s extremely easy to move an application from one server to another, and restarting the server is not necessary whenever a .php file is modified. The Django hackers really need to get together and figure a way to make this easier, because it’s really hard to sell the rest of the framework if putting an application online is so painful.


How programming is different from everything else

December 20, 2007

A story about a rather computer-challenged person was posted on the TheDailyWTF forums and that story found itself of prc. I read the story, found it funny like everybody else and I went to read the comments on reddit and one caught my eye:

“My brother in law apparently made several unsuccessful attempt to “learn programming” by opening up exes in Notepad.”

Hey, only real programmers write binaries with notepad. I’d be in awe.

I could be wrong, I haven’t asked any non-programmer for their point of view (because I’m anti-social and people hate me), but I think that this thought process of opening an executable file in a text editor to see how it works and fiddle with it makes sense.

Programming is a discipline where the thing you manipulate is completely different from the end result. A painter’s source code editor is his canvas and his executable program is the canvas, albeit in a different state. It’s the same with pottery, cooking, writing, knitting, etc. What you manipulate is your end result.

In the world of programming, you write words to describe how a process works, you pass those words into a machine (compiler, interpreter) and this machine creates another machine that does what the words you wrote told it too. I’m hard pressed to find a non-computer field where you have such a process. I have never heard of a cook putting his lasagna recipe (the actual page with the ingredients and manipulations) into the oven and the oven magically transforms it into his meal.

Us computer folks often sigh when people ask why their computer is slow to boot even though they have high speed Internet, but it seems to me that computing has no point of reference. You cannot say “oh this works kind of like this.” The entire experience is different from anything people have ever experienced.


Everybody should care what your code looks like

December 19, 2007

Jeff Atwood posted an article today titled Nobody Cares What Your Code Looks Like in which he discusses that end users couldn’t care less whether the underlying code is pretty. He’s probably right that users don’t care, however I think that users should care.

I don’t think I need to explain to any programmer that a ton of bugs can hide in ugly code, we learned it from books, from experience, from TheDailyWTF, etc. But users never see the code, they use a compiled version, and as long as it does what they want, they’re happy (sometimes, the software doesn’t even do what they want, but they’re happy nonetheless). So if something works, who cares about what it looks inside?

It’s quite simple: ugly == fragile. If a piece of code is ugly, if somebody just threw in a hack to make something work, it will eventually fuck up, and it will fuck up at the worst possible moment, Murphy’s Law.

Users care about the quality of the inner workings of plenty of things:

  • Nobody would buy a car that’s held together with duct tape, even if the car works
  • People won’t buy toys with lead in them, even if the toys are fun
  • People don’t want foods with trans fat in them, even if they taste good
  • Nobody would drive on a bridge with rotting beams, even if it’s still standing
  • etc.

There are plenty of situations where a person will give a crap how something is built and if the quality is good. In 2006, the De la Concorde overpass collapsed. An inquiry was opened and it was found that a cheaper concrete was used to build the overpass. People were outraged that lesser materials were used to build the overpassed.

It’s no different with computer programs: if a critical software (banking, healthcare, transporation, etc.) had a major failure and caused death, if the software was found to be fragile, that little care had been taken in writing the program, the public would certainly start blaming the programmers for such a sloppy job. And rightly so. They would care about the quality of the code.

“It works” is not enough; the underlying code must be good and robust to ensure that unexpected events don’t cause a crash, or that doing maintenance in the program won’t fuck it all up. Our entire lives depend on computer systems, is it so bad for programmers to want to make the internals clean and solid?


When you don’t even try…

December 6, 2007

I like to answer people’s programming questions on programming boards, but I highly dislike when somebody uses a forum to get his homework done instead of trying to find the answer himself. Here’s a case of a guy really abusing other people’s time. He asked *three* questions on how to use if. Doesn’t he have a book or something?

maxence45.png