#

## Django documentation

# How to use Django with mod_python

Apache with mod_python currently is the preferred setup for using Django on a production server.

mod_python is similar to mod_perl : It embeds Python within Apache and loads Python code into memory when the server starts. Code stays in memory throughout the life of an Apache process, which leads to significant performance gains over other server arrangements.

Django requires Apache 2.x and mod_python 3.x.

## Basic configuration

To configure Django with mod_python, first make sure you have Apache installed, with the mod_python module activated.

Then edit your `httpd.conf` file and add the following:

    <Location "/mysite/">
        SetHandler python-program
        PythonHandler django.core.handlers.modpython
        SetEnv DJANGO_SETTINGS_MODULE myproject.settings
        PythonDebug On
    </Location>

...and replace `myproject.settings` with the Python path to your settings file.

This tells Apache: "Use mod_python for any URL at or under '/mysite/', using the Django mod_python handler." It passes the value of `DJANGO_SETTINGS_MODULE` so mod_python knows which settings to use.

Also, if you've manually altered your `PYTHONPATH` to put your Django project on it, you'll need to tell mod_python:

    PythonPath "['/path/to/project'] + sys.path"

You can also add directives such as `PythonAutoReload Off` for performance. See the mod_python documentation for a full list of options.

Note that you should set `PythonDebug Off` on a production server. If you leave `PythonDebug On`, your users would see ugly (and revealing) Python tracebacks if something goes wrong within mod_python.

Restart Apache, and any request to /mysite/ or below will be served by Django. Note that Django's URLconfs won't trim the "/mysite/" -- they get passed the full URL.

When deploying Django sites on mod_python, you'll need to restart Apache each time you make changes to your Python code.

## Multiple Django installations on the same Apache

It's entirely possible to run multiple Django installations on the same Apache instance. Just use `VirtualHost` for that, like so:

    NameVirtualHost *

    <VirtualHost *>
        ServerName www.example.com
        # ...
        SetEnv DJANGO_SETTINGS_MODULE myproject.settings
    </VirtualHost>

    <VirtualHost *>
        ServerName www2.example.com
        # ...
        SetEnv DJANGO_SETTINGS_MODULE myproject.other_settings
    </VirtualHost>

If you need to put two Django installations within the same `VirtualHost`, you'll need to take a special precaution to ensure mod_python's cache doesn't mess things up. Use the `PythonInterpreter` directive to give different `<Location>` directives separate interpreters:

    <VirtualHost *>
        ServerName www.example.com
        # ...
        <Location "/something">
            SetEnv DJANGO_SETTINGS_MODULE myproject.settings
            PythonInterpreter myproject
        </Location>

        <Location "/otherthing">
            SetEnv DJANGO_SETTINGS_MODULE myproject.other_settings
            PythonInterpreter myproject_other
        </Location>
    </VirtualHost>

The values of `PythonInterpreter` don't really matter, as long as they're different between the two `Location` blocks.

## Running a development server with mod_python

If you use mod_python for your development server, you can avoid the hassle of having to restart the server each time you make code changes. Just set `MaxRequestsPerChild 1` in your `httpd.conf` file to force Apache to reload everything for each request. But don't do that on a production server, or we'll revoke your Django privileges.

## Serving media files

Django doesn't serve media files itself; it leaves that job to whichever Web server you choose.

We recommend using a separate Web server -- i.e., one that's not also running Django -- for serving media. Here are some good choices:

- lighttpd
- TUX
- A stripped-down version of Apache

If, however, you have no option but to serve media files on the same Apache `VirtualHost` as Django, here's how you can turn off mod_python for a particular part of the site:

    <Location "/media/">
        SetHandler None
    </Location>

Just change `Location` to the root URL of your media files. You can also use `<LocationMatch>` to match a regular expression.

This example sets up Django at the site root but explicitly disables Django for the `media` subdirectory and any URL that ends with `.jpg`, `.gif` or `.png`:

    <Location "/">
        SetHandler python-program
        PythonHandler django.core.handlers.modpython
        SetEnv DJANGO_SETTINGS_MODULE myproject.settings
    </Location>

    <Location "media">
        SetHandler None
    </Location>

    <LocationMatch "\.(jpg|gif|png)$">
        SetHandler None
    </LocationMatch>

## Serving the admin files

Note that the Django development server automagically serves admin media files, but this is not the case when you use any other server arrangement. You're responsible for setting up Apache, or whichever media server you're using, to serve the admin files.

The admin files live in (`django/contrib/admin/media`) of the Django distribution.

Here are two recommended approaches:

> 1. Create a symbolic link to the admin media files from within your document root. This way, all of your Django-related files -- code and templates -- stay in one place, and you'll still be able to `svn update` your code to get the latest admin templates, if they change.
> 2. Or, copy the admin media files so that they live within your document root.

## Comments

### krupan October 16, 2005 at 11:02 p.m.

Something that gave me a hard time: the user you run apache with needs read/write access to not only the sqlite database file, but to the directory that contains that file also. Apparently sqlite creates some temporary files in that directory as it goes.

### captnswing October 23, 2005 at 4:12 p.m.

hello all,
on mac os x, you need to install Apache2 in order to be able to use django with mod_python. This is not for everyone (I couldn't even get it to work once I went through all the trouble).

So I figured, FCGI with Apache 1.3 might be a better approach. And how to get that working, is now even documented: http://code.djangoproject.com/wiki/OsxFc...

hope its useful for some people
-captnswing

### Chetan Vaity October 31, 2005 at 1:44 a.m.

If you get this error,

EnvironmentError: Could not import DJANGO_SETTINGS_MODULE 'djangoSite.settings.main' (is it on sys.path?):

Check if your project directory is accessible by Apache. Most likely Apache will not have read permissions on your home directory.

### Mark Hurley November 8, 2005 at 9:44 p.m.

Using pysqlite2 and getting an error similar to...???
OperationalError: SQL logic error or missing database

1) Ensure you have installed sqlite2 and pysqlite2 or greater properly.
2) Ensure the location you place your filename.db is correctly set in the settings.py file.
3) Ensure the directory which contains the filename.db sqlite file has write permissions for the web user (i.e. apache for mod_php).
4) Ensure the filename.db file has write permissions by the web user as well.

### Arthur Hebert November 10, 2005 at 3:25 a.m.

Just a note on something that confused me for a while. For configurations that server multiple domain names, it probably makes more sense to use <Directory>...</Directory> instead of <Location>...</Location> like it says in the tutorial.

The two are very similar, but Location will apply to a sub-directory of all the domains that you serve, whereas Directory will apply to a specific domain (unless, of course, you have two domains pointing to the same source).

### Jaroslaw Zabiello November 18, 2005 at 3:20 p.m.

"SetHandler python-program" is used for older mod_python 2.x. For mod_python 3.x the correct phrase is: "SetHandler mod_python".

## Post a comment

Note: Please only use the comments for questions/critcisms/suggestions on the docs; if you experience errors please file a ticket, ask in the IRC channel, or post to the django-users list. Comments will be periodically reviewed, integrated into the documentation proper, and removed.

Your name:

Comment: