Deploying Django applications to a production server

Django is a Python-based open source Web application framework that focuses on making the process of creating database-driven Web sites and Web applications easier. Getting started with developing Django applications is simple, as a development Web server is included with the framework. However, this server is not suitable for use in a production environment, so further steps are required to deploy your Django application to the Web. In this article, you will learn about the Django framework and how to install it on your local machine. Discover how a Django application is made and about the automatic administration interface created for your application. You will then find out how to deploy your Django application to the Web on a server running Apache and mod_python. Finally, learn how Django applications can and should be scaled as your application's requirements grow.

Share:

Joe Lennon, Software developer, Core International

Joe Lennon photoJoe Lennon is a software developer from Cork, Ireland. He works as a Web application and Oracle PL/SQL developer for Core International, having graduated from University College Cork in 2007 with a degree in business information systems.


developerWorks Contributing author
        level

07 April 2009

Also available in Russian Japanese Portuguese

Django

Django is an open source Web development framework for the Python language that aims to automate as many processes as possible, allowing you to focus on developing software without worrying about reinventing the wheel. The framework is designed to be loosely coupled and tightly cohesive, meaning that different parts of the framework, while connected to one another, are not dependent on one another. This independence means you can use only the parts of Django you need, without worrying about dependency issues.

Django makes writing Web applications faster, and it drastically cuts down the amount of code required, making it much easier to maintain the application going forward. Django strictly observes the Don't Repeat Yourself (DRY) principle, whereby every distinct piece of code or data lives in only one place. This means that when a change needs to be made, it only needs to be made in one place, leading to the process of changing software becoming much faster and much easier.

Django was developed by a team of Web developers at the Lawrence Journal-World newspaper in 2003. Under pressure to release applications and enhancements under severe time constraints, they decided to create a Web framework that would save them time, allowing them to meet their difficult deadlines. The team released the framework as open source software in July 2005, and it is now developed by a community of thousands of developers across the world.

The Django framework is released under the Berkeley Software Distribution (BSD) open source license, which permits redistribution and reuse of the source code and binary, with or without modification, so long as the copyright notice, license conditions, and disclaimer are retained in the redistributed package. These items must also be present in the redistributed software's documentation and supplementary materials where applicable. And the license specifies that neither the Django name nor the names of Django contributors can be used to endorse or promote derivative products without express written permission.


Setting up a basic Django development environment

Fortunately, installing Django is straightforward, so setting up a development environment is quick and easy. Django is written entirely in Python, so to install Django, you first need to install Python. If you're using Mac OS X or Linux®, it's likely that Python is already on your machine. Simply run python in your shell (use Terminal.app on a Mac) and you should see something like Listing 1.

Listing 1. Make sure Python is running
$ python
Python 2.5.1 (r251:54863, Nov 11 2008, 17:46:48) 
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
Listing 1 - Checking for Python on Mac OS X

As long as your system has a version of Python from 2.3 to 2.6, you will be able to install Django. If you are a Microsoft® Windows® user or if you need to upgrade to a newer version, download Python. A simple installation package is available for Windows users, so installing Python couldn't be much easier.

When you have verified that Python is installed on your computer, you can proceed to install Django. There are three options: installing an official release, installing a distribution-specific installation package, or installing the latest "trunk" version from Subversion. For the sake of this article, I will only walk through the installation from an official release. For information about installing the trunk version, see the official documentation instructions (see Resources).

The first step in installing the official Django release is to get the tarball from the Django download page. Once you have downloaded this file, extract its contents. In Linux, simply issue the following command at your shell prompt (be sure to navigate to the directory where you downloaded the package to). Please note that V1.0.2 was the latest release at the time of writing, so be sure to replace this file name with the exact filename of the package you downloaded: tar zxvf Django-1.0.2-final.tar.gz.

In Mac OS X, it's likely that your Web browser automatically decompressed the package when it finished downloading, so the file will be Django-1.0.2-final.tar. To extract this file, simply use the following command: tar xvf Django-1.0.2-final.tar. If you are using Windows, you can use a utility such as 7-Zip to extract the tarball.

Now that you have extracted the contents of the tarball (probably to a location like Django-1.0.2-final on your hard drive), navigate to that folder in your command prompt. To install Django, issue the following command (Mac OS X or Linux): sudo python setup.py install. Windows users, make sure your command prompt is opened with administrator privileges and issue the following command: setup.py install.

Once you have done this, Django will have been installed into your Python installation's site-packages folder, and you are ready to start developing in Django. Before we move onto the anatomy of a Django application, we will test that our development environment is up and running correctly. First, we will check that Django is installed correctly. Open your shell or command prompt and start the Python interactive tool by issuing the command python. Now issue the commands shown in Listing 2 at the Python prompt (don't type the >>>s):

Listing 2. Verify that Django is installed correctly
>>> import django
>>> django.VERSION

If your installation was successful, you should see the text shown in Listing 3.

Listing 3. Successful installation
(1, 0, 2, 'final', 0)
>>>

Now that we have verified that Django is actually installed, we will test that the development server is working. To do this, we need to create a project. Create a directory to store your Django projects in (I use /home/joe/django on my Mac OS X system) and navigate to that directory. From there, issue the following command: django-admin.py startproject testproject.

This will create a new directory within your projects directory called testproject. This directory contains four files: __init__.py, manage.py, settings.py, and urls.py. Don't worry about what these files do right now; we are going to jump ahead and run the project. Make sure you are in the project folder (use cd testproject at the prompt) and issue the following command: python manage.py runserver. You should see the output shown below.

Listing 4. Running the Django development server
Validating models...
0 errors found

Django version 1.0.2 final, using settings 'testproject.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

This message tells us that the development server is now running at the URL http://127.0.0.1:8000/. Open your favorite Web browser and paste in this URL in the address bar. You should see a page like the one shown below.

Figure 1. Welcome to Django Page
Welcome to Django Page

You now have a working Django development environment up and running. It's worth mentioning that although you can run full-fledged Django applications in this environment, it is not suitable for use in a production environment. We will cover deploying Django applications for production use later in this article.


The anatomy of a Django application

Django's architecture is loosely based on the Model-View-Controller (MVC) pattern in that it separates application logic, user interface (UI), and data-access layers, with the goal of allowing each layer to be modified independently, without affecting the other layers. According to Django documentation, however, Django follows a similar pattern: what it refers to as a Model-Template-View (MTV) architecture. The Model can be seen as the data-access layer, where the application interacts with any databases and information sources. The Template is the layer that defines how the data should be presented to the user, whereas this is considered the View layer in an MVC pattern. In an MTV architecture, the View layer describes what data should be presented to the user. It does not define exactly how it should be presented; it delegates that task to the template layer. As for MVC's Controller layer, Django sees this as being the framework itself, as it determines the appropriate view to send requests to, as defined in the URL configuration.

In addition to Models, Templates, and Views, Django offers some advanced features out of the box, such as URL configurations, an automatic administrative interface, caching, and more. Like Python, one of the key philosophies behind Django is the batteries-included approach, meaning that it comes with a large standard library of additional packages you can use in your applications without additional downloads.

The model layer of a Django application is handled by Django's data-access layer. Within this layer, you will find everything related to the data: connection settings, validation parameters, relations, etc. Out of the box, Django includes support for PostgreSQL (the preferred database of the creators of Django), MySQL, SQLite, and Oracle. Which database to use is stored in a settings file, and the model layer is the same no matter what option you choose.

Models in Django can be seen as descriptions of the database table schemas, represented in Python code. Django uses the model to generate and execute SQL statements in the database, which in turn return a result. Django then translates to a Python data structure, which can be used by your Django application. An obvious advantage here is that you can hot-swap among different databases systems (for example, change from MySQL to PostgreSQL) without having to change your models.

The code in Listing 5 is an example of a model definition. This would generally be stored in a models.py file in a Django application's directory.

Listing 5. Sample Django Model
from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    email = models.EmailField()
    date_of_birth = models.DateField()

The Template layer of a Django application allows you to separate the UI or presentation layout of a Web application from its data. It uses placeholder variables and simple logic statements to define what data should be populated into the template. Templates usually produce HTML output, but can also produce XML or any other type of document.

The idea behind the Template layer is that the presentation layer code is separate from the business-layer code. This means a Python developer can focus on developing the software, while leaving a Web designer to work on the templates. It also means that the developer and the designer can work on the same project at the same time, as the two components are completely separate from one another.

It's important to note that Django's template system does not allow Python code to be executed directly from the template. It offers a rudimentary set of programming-style features, such as variables, logic statements (if statements), and looping constructs (for loops), which should offer more than enough logic required for the presentation of data. Listing 6 is an example of what a Django template would look like.

Listing 6. Sample Django Template
<html> <head>
<title>Your message has been sent</title>
</head>
<body>
<h1>Thank you!</h1>
<p>Just wanted to say a quick thanks, {{ name }}, for the message you have just
    sent.</p>
<p>It was sent on {{ sent_date|date:"j F Y" }}. We aim to respond within 
    48 hours.</p>
<p>Thanks again!</p>
</body>
</html>

Listing 7 shows how this template would be used in a Django application.

Listing 7. Loading the sample Django Template in a view
def send_message(request):
    name = "Joe Lennon"
    sent_date = datetime.datetime.now()
    return render_to_response('thankyou.html', locals())

View functions, or "views" as they are more commonly known, are basically Python functions that accept a request parameter and return a response. The request is typically a request from the Web server, and the view takes any parameters passed along with this request. The view then performs the logic required to determine the appropriate response before returning that response. Views can be stored anywhere in a Django application, but are usually stored in a file named views.py. Listing 5 is an example of a view function, named send_message. It accepts the request parameter in its definition and returns a rendered template (thankyou.html) as its response.

You just read that views can be stored anywhere. If that is the case, how does Django know where to find them? This leads us on to URLconfs, which define what URLs point to what views. URLconfs are stored in a file called urls.py and basically map a URL to a view function. For example, the url /send_message/ might map to our send_message view, as described in Listing 7. In fact, the way URLconfs work allows them to be used for pretty URLs out of the box — in other words, instead of using query strings like myfile.php?param1=value1, your URL might be /myfile/value1/.

The code is Listing 8 provides an example of a urls.py file, which connects the URL /send_message/ to our send_message view function, as defined in Listing 7.

Listing 8. Sample URLconf
from django.conf.urls.defaults import *
from testproject.views import send_message

urlpatterns = patterns('',
    ('^send_message/$', send_message),
)

One of the most interesting and talked-about features of Django is its automatic administrative interface. Web application developers who have worked on projects that require back-end admin interfaces to be developed in addition to the front end may be able to relate to the frustration and boredom that comes from developing such interfaces. Admin interfaces are usually mind-numbing, don't require much skill, and don't flex your programming muscle in any way. Django's automatic admin interface feature will be of enormous value, as it takes this requirement out of the equation by automating the entire task.

Once you have created the models for your application and set up your database settings, you can enable the admin interface for your application. Once you have done so, simply point your browser to http://127.0.0.1:8000/admin/ and log in to manage the back end of your Django application. The interface is highly customizable and features excellent user and group-based authentication controls. A screenshot of it in action is shown below.

Figure 2. Django automatic admin interface in action
Django automatic admin interface in action

We have given a high-level overview of how a Django application is created and of how the MTV pattern it is based on works. We have looked at the concepts of models, templates, views, and URLconfs; and we have seen a glimpse of Django's brilliant automatic administration interface system. If you are looking for an in-depth guide to developing Django applications, visit the official Django project Web site and read the documentation there or read the Django Book (see Resources). Both offer an excellent assumption-free guide to all things Django and cover much more detail than we can get into here.

Next, take a look at taking Django applications and deploying them to production servers.


Readying your Django application for deployment

As we have seen, the Django framework conveniently includes a development server, which is ideal for debugging and testing your Django application. Unfortunately, this server is only designed to run in a local environment and could not withstand the pressures of a production Web application used by many people concurrently. For that, you need to deploy Django to a production-grade Web server, such as Apache or lighttpd. Explore some steps that need to be taken to make your application production-ready, then learn what's involved in preparing your Web server for serving up your Django application.

Before discussing how to set up your production environment for your Django application, there are a few things you need to do in your Django application's settings. It is important to make these changes because any vulnerabilities in your Django application may be made public, thanks to debug error messages, etc.

Naturally, you won't want to change these settings in your development environment, as debug messages and errors are extremely useful when maintaining your application. To solve this, you could maintain two separate settings files: one for your development server and one for your production server. Alternatively, you could employ the following trick to keep them in the same file and tell Django to only use the development settings if it is in the development environment. To do this, you would lay out your settings.py file in the following way (obviously, replace joe-mac-mini with your development server's hostname, as shown in Listing 9).

Listing 9. Separate settings for development and production environments
import socket
if socket.get_hostname() == 'joe-mac-mini':
    #Development Server Settings go here
else:
    #Production Server Settings go here

Now that we've looked at keeping separate settings for our two environments, let's examine the settings we need to change in our production environment. The two essential settings you must change in your production environment are DEBUG and TEMPLATE_DEBUG. These are set to True by default when you create your Django application using django-admin.py startproject. It is essential that you change this to False for your production environment. In your settings.py, in the Production section, this line should read as follows: DEBUG = TEMPLATE_DEBUG = False.

By default, Django is set up to send an e-mail anytime an unhandled exception is raised in your Django application. To enable this feature, tell Django who it should send the e-mail to. This is done with the ADMINS setting in the settings.py file.

Listing 10. Defining application administrators
ADMINS = (
    ('Joe Lennon', 'joe@joelennon.ie'),
)

If you come across errors in your code when developing your Django application, you may have noticed the error pages Django generates, full of helpful information to assist you in finding the root of the problem. When you switch debug mode off, these nice error pages disappear, as they are a potential security threat. As a result, if someone comes across an error (for example, a 404 Page Not Found, 403 Forbidden, or 500 Internal Server Error), he will only see an ugly error code page. To rectify this, it is advised to create nice, explanatory error template pages and put them in your application's template folder. Each template should be named according to the error code it represents. For Page Not Found, you should name the file 404.html; for Internal Server Error, use 500.html; etc.

Now that we have configured our settings for use in a production environment, we will show you how this environment should be set up to house your Django application. Although it is possible to run Django using FastCGI and lighttpd, a more typical setup is Apache and mod_python. We will now look at how to deploy to a server running Apache and mod_python. Then we'll take a brief look at deploying to a shared Web-hosting environment, where access to httpd.conf is forbidden.


Deploying Django applications to Apache with mod_python

According to the Django documentation, a setup of the Apache Web server running mod_python is the recommended option for deploying Django applications. Django supports setups with at least Apache HTTP Server V2.0 and mod_python V3.0 and later. mod_python is an Apache module that integrates support for the Python programming language into the Web server. It is much faster than the traditional CGI method of executing Python scripts.

To load the mod_python module into Apache, add the following line to your server's httpd.conf file: LoadModule python_module /usr/lib/apache2/modules/mod_python.so.

In addition to loading the mod_python module, you also need to set up a Location directive that tells Apache what URL to associate with your Django application. For the sake of example, the settings here are what would apply to the testproject project created earlier.

Listing 11. testproject Location directive
<Location "/testproject">
    SetHandler python-program
    PythonHandler django.core.handlers.modpython
    SetEnv DJANGO_SETTINGS_MODULE testproject.settings
    PythonDebug Off
</Location>

This tells Apache that your Django testproject project is accessible via the /testproject URL. For example, if your server's domain name is example.com, your application would be accessible via http://www.example.com/testproject/. To load these new settings into Apache, simply restart the Apache server.

Django's developers highly recommend that you do not serve media files (such as images, video, audio, etc.) from the same Web server as your Web application, but in many cases, that is not an option — at least initially. In order to set up an area of your Web site where media files can be served, you can add the following directive to your httpd.conf file.

Listing 12. Telling Apache not to use mod_python for media files
<LocationMatch "\.(png|gif|jpg|mov|mp3|avi|wav)$">
    SetHandler None
</LocationMatch>

That's all there is to setting up Apache and mod_python for deploying Django to a production Web server. Next, we'll take a look at a common deployment scenario where someone is deploying to a shared Web-hosting server where they are not allowed to modify httpd.conf.


Deploying Django applications to a shared Web-hosting environment

Unfortunately, dedicated servers and virtual private servers tend to be quite expensive and, as a result, these are not viable options for deployment for everyone. It is common that you will first deploy a Web application on a shared hosting environment, upgrading to dedicated solutions as the application grows in popularity. Luckily, most shared Web-hosting providers include Python support, so it is possible to deploy Django applications in this scenario.

Unlike a dedicated environment, end users typically do not have the option of running a separate server process or editing the httpd.conf configuration file. This means they cannot make the changes outlined in the previous section, so they cannot get Django up and running in this manner. Fortunately, it is possible to deploy Django to shared hosting environments, using Web server-spawned processes that execute a FastCGI program. Create a file called .htaccess and place it in the same directory you are deploying your Django application to.

Listing 13. .htaccess file
AddHandler fastcgi-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ testproject.fcgi/$1 [QSA,L]

Then create a small Python script that informs Apache of the various settings for your Django project and executes the FastCGI program. The name of the file is not important, but it must be the same as the file name in the RewriteRule line of .htaccess. In Listing 14, we used the file name testproject.fcgi, so that's what I will call my script.

Listing 14. testproject.fcgi file
#!/usr/bin/python
import sys, os
sys.path.insert(0, "/home/joelennon/python")
os.environ['DJANGO_SETTINGS_MODULE'] = "testproject.settings"

from django.core.servers.fastcgi import runfastcgi
runfastcgi(method="threaded", daemonize="false")

Be sure to make the file executable. If you have shell access to your shared hosting server, log in and change to the directory the file is contained in and run chmod 755 testproject.fcgi.

If you do not have shell access, you can change file permissions with most decent FTP clients. Anytime you change your application's code, you need to change the timestamp on this file. This tells Apache that the application has been updated, and it will continue to restart your Django application. If you have shell access, this is as simple as running touch testproject.fcgi. If you do not have shell access, you can update the timestamp of the file by reuploading it or by editing it and resaving it.

If you prefer not to get your hands dirty with these configuration files, you could always avail of a hosting service designed to support Django applications out of the box. The popular MediaTemple hosting provider offers a Django GridContainer add-on to its GridService offering, starting from $20/month for 256 MB of RAM. The GridContainer runs on a pre-tuned lighttpd/FastCGI setup, and the amount of RAM can be increased to scale along with your application.


Scaling your Django deployment

If your Django application is successful, it is likely that you will need your deployment to be as scalable as possible. It's common for Web applications to work fine under average loads, but phenomena like the Digg effect can forward so much traffic to the application that it buckles under the surge in load. Fortunately, Django and Python are highly scalable by nature, but there are other things you need to consider as your application grows.

If you are running your Django application on a shared hosting environment and are starting to feel that it is outgrowing the limited resources available to it in such a space, your obvious first port of call is the move to a dedicated machine. If cost is an issue, virtual private servers offer an inexpensive intermediary between shared hosting and a dedicated server.

As your application grows, even the resources of a dedicated server can become sparse very quickly. The following are some remedies that may ease the burden on your server:

  • Turn off any unused processes or daemons, such as mail servers, streaming servers, gaming servers or any other unnecessary processes, that are hogging precious CPU time and RAM.
  • Farm off your media files to a cloud platform, such as Amazon S3. This will allow you to only use your Web server for Django requests and keep your media on a separate server.
  • Turn off Apache's Keep-Alive option. Keep-Alive is an extension to the HTTP protocol, which allows persistent connections over HTTP. This, in turn, allows multiple requests to be sent down over the same TCP connection, dramatically speeding up the serving of static HTML documents and images. Unfortunately, this extension can have a negative effect on the performance of a Django application. Please note that you should only turn this option off if you have moved your media files to a different server. To turn off Keep-Alive, find the relevant line in your httpd.conf file and change it to Keep-Alive Off.
  • Use Django's built-in cache framework. It is powered by memcached, a popular distributed memory-object caching system. Effective caching can drastically enhance the performance of your Django applications.
  • Upgrade your server. Dedicate as much RAM as possible, and if disk space is an issue, consider adding a new disk. If your server is struggling, it's more than likely that it's due to the RAM being used up. Don't waste your money upgrading processors — spend the money on RAM, instead.
  • Buy another server. There may come a time when your server just can't handle the load from your Django application on its own. As soon as your single server setup starts to give way, add another server. You should run your Web server on one machine and your database server on the other. Be sure to use the machine with more RAM for your database server. If required, upgrade the new machine with more RAM and disk space when necessary.
  • Use database replication. If your database server is running out of resources, you can ease the burden by replicating it across more than one server. Once replication is in place, you can add servers when required to provide additional resources.
  • Add redundancy. With large-scale applications, having a single point of failure for your Web server or database server is a disaster waiting to happen. You should add redundant servers where possible, which will take over in the event of the primary server failing. Additionally, using load-balancing hardware or software, such as mod_proxy, to distribute the traffic across your servers can drastically increase the performance of your application.

It is important to consider a scaling path for your Django application as early as possible. This allows you to put a plan of action in place that covers every possible scenario. So, if the Digg effect has your application on its knees, you can simply kick the next stage of your scaling plan into action and embrace your new users with open arms — and more importantly, a fast-running application.


Summary

We have looked at the Django framework from both ends of the spectrum — from a developer with no prior experience using the framework starting out to someone who has a fully ready Django application waiting to be deployed looking for a guide on how to tackle deploying the application to the Web. We've also examined what to consider in terms of scalability for the future. We looked at what a Django application is made up of and learned about the Model-Template-View (MTV) pattern it is based on. We have seen that Django is a lightweight, easy-to-install, and easy-to-learn framework with excellent documentation and a vibrant community surrounding it, making it a great framework for your next Web application.

Resources

Learn

  • Check out the Django documentation for a plethora of tutorials and articles about Django and how to use it to develop powerful Web applications.
  • Django Book: Read a free online version of an excellent book about Django, covering everything from introductory concepts to deployment, internationalization and security.
  • Dive Into Python: Read a free online version of this comprehensive book on the Python programming language.
  • Read the Wikipedia entry for Django.
  • Visit DjangoSnippets.org for a multitude of reusable, user-contributed Django code snippets you can freely use in your own projects.
  • "Develop for the Web with Django and Python" offers an in-depth guide to the fundamentals of developing with the Django framework.
  • developerWorks Web development zone: Expand your site development skills with articles and tutorials that specialize in Web technologies.
  • To listen to interesting interviews and discussions for software developers, check out developerWorks podcasts.
  • Stay current with developerWorks' Technical events and webcasts.
  • Follow developerWorks on Twitter.
  • Check out upcoming conferences, trade shows, webcasts, and other Events around the world that are of interest to IBM open source developers.
  • Visit the developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products.
  • Watch and learn about IBM and open source technologies and product functions with the no-cost developerWorks On demand demos.

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Open source on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source, Web development
ArticleID=379949
ArticleTitle=Deploying Django applications to a production server
publish-date=04072009