This is the second in my series that I am calling “Eddie’s Practices” for Django, in which I present tips and tricks that I have gleaned over the years of working with the Django web application framework. If you haven’t seen Eddie’s Django Tip #1: Choose Names Carefully, why not take a look at it now?
Today’s tip is:
Don’t Get Trapped in the Django Universe
One of Django’s strengths is its “batteries included” approach. It provides for free many of the features you would normally have to write from scratch or cobble together from disparate sources. Some examples are the authentication system, the administrative interface, and the templating system. These are wonderfully useful, and they often work together in ways that separately developed libraries can not. However, not every part of Django will fit your needs all the time. Choices were made in the design of Django, and those aren’t always the same choices you would have made.
Fortunately, another strength of Django is its modularity. It is very easy to unplug one of its built-in features and plug in your own or someone else’s. I’ll go through some of the Django features that you may want to consider replacing or eliminating.
The important point I want to emphasize is that there is nothing unclean or dangerous about doing this. It’s your site, you’re the boss of Django, and you should only use the parts of it that you need. I think the creators of Django would agree with me.
The Templating System
There is nothing sacred about the Django templating system, and no reason you have to use it in your application. In fact, the more I use Django templates, the more I appreciate the power and flexibility of Cheetah, and so in most of my recent projects I have used Cheetah for my templates. You do lose out on some of the generic templates and template tags that Django provides, but these are easily replaced, especially because Cheetah allows calling arbitrary Python functions from within a template. As a solo developer, I find this power very convenient.
If there is interest, I will be happy to share some of the functions and code I have developed to make it easier to use Cheetah within Django.
The Authentication System
Django makes it very easy to replace or change the built-in authentication/authorization system. You might want to do this if you already have a system in place: for example, if you use HTTP authentication via Apache. Likewise if you want to do something wacky like authentication by IP address within an intranet. Or maybe you have a completely public site with no need for authentication at all.
The simplest way to customize your authentication is to provide a custom Authentication Backend. But you could go so far as to completely replace or eliminate the
django.contrib.auth app. Just be aware that the Django admin site relies on
The Object-Relational Mapping (ORM)
QuerySet interface is great for abstracting away the details of database operations, so it is rare that you need to write raw SQL. So much so, in fact, that you can write a complicated application without even knowing SQL. This is a bad idea, however.
Learn SQL, learn what Django is doing behind the scenes with your queries, and don’t be afraid to use raw SQL when it is appropriate. There are some things you just can’t do with Django’s ORM: for example, any operation that involves reading and updating a field atomically. Other operations are just much faster if you can do them raw. A good rule of thumb is that if you are performing queries or updates inside a Python loop, investigate switching it to SQL. One big query is generally much faster than a bunch of smaller queries.
The Database Itself
Yes! Despite what you may have heard, it is possible to create a web application without a database! In fact, for a recent site I developed I did just that. I use Django in a very bare-bones way: Django provides URL parsing and dispatching, a logical source code layout, the handling of HTTP requests and responses, and some utility functions, but that’s it. Apache takes care of authentication, Cheetah handles my templates, and I store user data in a JSON formatted text file. With no database, there is no need for an admin site – I can edit the text files directly in the file system. There are valid reasons for all these decisions, and for this project they fit my needs perfectly. It’s still a “Django-powered” site, but only in a very limited sense.
This should go without saying, but for many new developers it needs to be said. A web application does not need a web framework. Blasphemy, I know. But CGI has been around since 1993. Django was created in 2003, and didn’t go public for a while after that. So we had ten good years of dynamic web pages before Django even was a glimmer. If you’ve never done it before, I recommend making at least one pure CGI (or FastCGI) app, so you can better know and understand what Django is doing behind the scenes. It’s not magic or mystical or even that difficult. Just as driving a stick-shift makes you a better driver even on an automatic, knowing the details of web protocols will make you a better web developer.
Then when you go back to Django you will appreciate all that it is doing for you, as well as realizing that the Django way is not the only way.