Plain Text | 412 lines | 314 code | 98 blank | 0 comment | 0 complexity | 4148d0a459d44c5795899360bb2a67a6 MD5 | raw file
1============================================ 2How to use Django with Apache and mod_python 3============================================ 4 5.. warning:: 6 7 Support for mod_python has been deprecated, and will be removed in 8 Django 1.5. If you are configuring a new deployment, you are 9 strongly encouraged to consider using :doc:`mod_wsgi 10 </howto/deployment/modwsgi>` or any of the other :doc:`supported 11 backends </howto/deployment/index>`. 12 13.. highlight:: apache 14 15The `mod_python`_ module for Apache_ can be used to deploy Django to a 16production server, although it has been mostly superseded by the simpler 17:doc:`mod_wsgi deployment option </howto/deployment/modwsgi>`. 18 19mod_python is similar to (and inspired by) `mod_perl`_ : It embeds Python within 20Apache and loads Python code into memory when the server starts. Code stays in 21memory throughout the life of an Apache process, which leads to significant 22performance gains over other server arrangements. 23 24Django requires Apache 2.x and mod_python 3.x, and you should use Apache's 25`prefork MPM`_, as opposed to the `worker MPM`_. 26 27.. seealso:: 28 29 * Apache is a big, complex animal, and this document only scratches the 30 surface of what Apache can do. If you need more advanced information about 31 Apache, there's no better source than `Apache's own official 32 documentation`_ 33 34 * You may also be interested in :doc:`How to use Django with FastCGI, SCGI, 35 or AJP </howto/deployment/fastcgi>`. 36 37.. _Apache: http://httpd.apache.org/ 38.. _mod_python: http://www.modpython.org/ 39.. _mod_perl: http://perl.apache.org/ 40.. _prefork MPM: http://httpd.apache.org/docs/2.2/mod/prefork.html 41.. _worker MPM: http://httpd.apache.org/docs/2.2/mod/worker.html 42.. _apache's own official documentation: http://httpd.apache.org/docs/ 43 44Basic configuration 45=================== 46 47To configure Django with mod_python, first make sure you have Apache installed, 48with the mod_python module activated. 49 50Then edit your ``httpd.conf`` file and add the following:: 51 52 <Location "/mysite/"> 53 SetHandler python-program 54 PythonHandler django.core.handlers.modpython 55 SetEnv DJANGO_SETTINGS_MODULE mysite.settings 56 PythonOption django.root /mysite 57 PythonDebug On 58 </Location> 59 60...and replace ``mysite.settings`` with the Python import path to your Django 61project's settings file. 62 63This tells Apache: "Use mod_python for any URL at or under '/mysite/', using the 64Django mod_python handler." It passes the value of :ref:`DJANGO_SETTINGS_MODULE 65<django-settings-module>` so mod_python knows which settings to use. 66 67Because mod_python does not know we are serving this site from underneath the 68``/mysite/`` prefix, this value needs to be passed through to the mod_python 69handler in Django, via the ``PythonOption django.root ...`` line. The value set 70on that line (the last item) should match the string given in the ``<Location 71...>`` directive. The effect of this is that Django will automatically strip the 72``/mysite`` string from the front of any URLs before matching them against your 73URLconf patterns. If you later move your site to live under ``/mysite2``, you 74will not have to change anything except the ``django.root`` option in the config 75file. 76 77When using ``django.root`` you should make sure that what's left, after the 78prefix has been removed, begins with a slash. Your URLconf patterns that are 79expecting an initial slash will then work correctly. In the above example, 80since we want to send things like ``/mysite/admin/`` to ``/admin/``, we need 81to remove the string ``/mysite`` from the beginning, so that is the 82``django.root`` value. It would be an error to use ``/mysite/`` (with a 83trailing slash) in this case. 84 85Note that we're using the ``<Location>`` directive, not the ``<Directory>`` 86directive. The latter is used for pointing at places on your filesystem, 87whereas ``<Location>`` points at places in the URL structure of a Web site. 88``<Directory>`` would be meaningless here. 89 90Also, if your Django project is not on the default ``PYTHONPATH`` for your 91computer, you'll have to tell mod_python where your project can be found: 92 93.. parsed-literal:: 94 95 <Location "/mysite/"> 96 SetHandler python-program 97 PythonHandler django.core.handlers.modpython 98 SetEnv DJANGO_SETTINGS_MODULE mysite.settings 99 PythonOption django.root /mysite 100 PythonDebug On 101 **PythonPath "['/path/to/project'] + sys.path"** 102 </Location> 103 104The value you use for ``PythonPath`` should include the parent directories of 105all the modules you are going to import in your application. It should also 106include the parent directory of the :ref:`DJANGO_SETTINGS_MODULE 107<django-settings-module>` location. This is exactly the same situation as 108setting the Python path for interactive usage. Whenever you try to import 109something, Python will run through all the directories in ``sys.path`` in turn, 110from first to last, and try to import from each directory until one succeeds. 111 112Make sure that your Python source files' permissions are set such that the 113Apache user (usually named ``apache`` or ``httpd`` on most systems) will have 114read access to the files. 115 116An example might make this clearer. Suppose you have some applications under 117``/usr/local/django-apps/`` (for example, ``/usr/local/django-apps/weblog/`` and 118so forth), your settings file is at ``/var/www/mysite/settings.py`` and you have 119specified :ref:`DJANGO_SETTINGS_MODULE <django-settings-module>` as in the above 120example. In this case, you would need to write your ``PythonPath`` directive 121as:: 122 123 PythonPath "['/usr/local/django-apps/', '/var/www'] + sys.path" 124 125With this path, ``import weblog`` and ``import mysite.settings`` will both 126work. If you had ``import blogroll`` in your code somewhere and ``blogroll`` 127lived under the ``weblog/`` directory, you would *also* need to add 128``/usr/local/django-apps/weblog/`` to your ``PythonPath``. Remember: the 129**parent directories** of anything you import directly must be on the Python 130path. 131 132.. note:: 133 134 If you're using Windows, we still recommended that you use forward 135 slashes in the pathnames, even though Windows normally uses the backslash 136 character as its native separator. Apache knows how to convert from the 137 forward slash format to the native format, so this approach is portable and 138 easier to read. (It avoids tricky problems with having to double-escape 139 backslashes.) 140 141 This is valid even on a Windows system:: 142 143 PythonPath "['c:/path/to/project'] + sys.path" 144 145You can also add directives such as ``PythonAutoReload Off`` for performance. 146See the `mod_python documentation`_ for a full list of options. 147 148Note that you should set ``PythonDebug Off`` on a production server. If you 149leave ``PythonDebug On``, your users would see ugly (and revealing) Python 150tracebacks if something goes wrong within mod_python. 151 152Restart Apache, and any request to ``/mysite/`` or below will be served by 153Django. Note that Django's URLconfs won't trim the "/mysite/" -- they get passed 154the full URL. 155 156When deploying Django sites on mod_python, you'll need to restart Apache each 157time you make changes to your Python code. 158 159.. _mod_python documentation: http://modpython.org/live/current/doc-html/directives.html 160 161Multiple Django installations on the same Apache 162================================================ 163 164It's entirely possible to run multiple Django installations on the same Apache 165instance. Just use ``VirtualHost`` for that, like so:: 166 167 NameVirtualHost * 168 169 <VirtualHost *> 170 ServerName www.example.com 171 # ... 172 SetEnv DJANGO_SETTINGS_MODULE mysite.settings 173 </VirtualHost> 174 175 <VirtualHost *> 176 ServerName www2.example.com 177 # ... 178 SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings 179 </VirtualHost> 180 181If you need to put two Django installations within the same ``VirtualHost`` 182(or in different ``VirtualHost`` blocks that share the same server name), 183you'll need to take a special precaution to ensure mod_python's cache doesn't 184mess things up. Use the ``PythonInterpreter`` directive to give different 185``<Location>`` directives separate interpreters:: 186 187 <VirtualHost *> 188 ServerName www.example.com 189 # ... 190 <Location "/something"> 191 SetEnv DJANGO_SETTINGS_MODULE mysite.settings 192 PythonInterpreter mysite 193 </Location> 194 195 <Location "/otherthing"> 196 SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings 197 PythonInterpreter othersite 198 </Location> 199 </VirtualHost> 200 201The values of ``PythonInterpreter`` don't really matter, as long as they're 202different between the two ``Location`` blocks. 203 204Running a development server with mod_python 205============================================ 206 207If you use mod_python for your development server, you can avoid the hassle of 208having to restart the server each time you make code changes. Just set 209``MaxRequestsPerChild 1`` in your ``httpd.conf`` file to force Apache to reload 210everything for each request. But don't do that on a production server, or we'll 211revoke your Django privileges. 212 213If you're the type of programmer who debugs using scattered ``print`` 214statements, note that output to ``stdout`` will not appear in the Apache 215log and can even `cause response errors`_. 216 217.. _cause response errors: http://blog.dscpl.com.au/2009/04/wsgi-and-printing-to-standard-output.html 218 219If you have the need to print debugging information in a mod_python setup, you 220have a few options. You can print to ``stderr`` explicitly, like so:: 221 222 print >> sys.stderr, 'debug text' 223 sys.stderr.flush() 224 225(note that ``stderr`` is buffered, so calling ``flush`` is necessary if you wish 226debugging information to be displayed promptly.) 227 228A more compact approach is to use an assertion:: 229 230 assert False, 'debug text' 231 232Another alternative is to add debugging information to the template of your page. 233 234Serving media files 235=================== 236 237Django doesn't serve media files itself; it leaves that job to whichever Web 238server you choose. 239 240We recommend using a separate Web server -- i.e., one that's not also running 241Django -- for serving media. Here are some good choices: 242 243 * lighttpd_ 244 * Nginx_ 245 * TUX_ 246 * A stripped-down version of Apache_ 247 * Cherokee_ 248 249If, however, you have no option but to serve media or static files on the 250same Apache ``VirtualHost`` as Django, here's how you can turn off mod_python 251for a particular part of the site:: 252 253 <Location "/media"> 254 SetHandler None 255 </Location> 256 257Just change ``Location`` to the root URL of your media files. You can also use 258``<LocationMatch>`` to match a regular expression. 259 260This example sets up Django at the site root but explicitly disables Django 261for the ``media`` and ``static`` subdirectories and any URL that ends with 262``.jpg``, ``.gif`` or ``.png``:: 263 264 <Location "/"> 265 SetHandler python-program 266 PythonHandler django.core.handlers.modpython 267 SetEnv DJANGO_SETTINGS_MODULE mysite.settings 268 </Location> 269 270 <Location "/media"> 271 SetHandler None 272 </Location> 273 274 <Location "/static"> 275 SetHandler None 276 </Location> 277 278 <LocationMatch "\.(jpg|gif|png)$"> 279 SetHandler None 280 </LocationMatch> 281 282.. _lighttpd: http://www.lighttpd.net/ 283.. _Nginx: http://wiki.nginx.org/Main 284.. _TUX: http://en.wikipedia.org/wiki/TUX_web_server 285.. _Apache: http://httpd.apache.org/ 286.. _Cherokee: http://www.cherokee-project.com/ 287 288Serving the admin files 289======================= 290 291Note that the Django development server automagically serves the static files 292of the admin app, but this is not the case when you use any other server 293arrangement. You're responsible for setting up Apache, or whichever media 294server you're using, to serve the admin files. 295 296The admin files live in (:file:`django/contrib/admin/static/admin`) of the 297Django distribution. 298 299We **strongly** recommend using :mod:`django.contrib.staticfiles` to handle 300the admin files, but here are two other approaches: 301 302 1. Create a symbolic link to the admin static files from within your 303 document root. 304 305 2. Or, copy the admin static files so that they live within your Apache 306 document root. 307 308Using "eggs" with mod_python 309============================ 310 311If you installed Django from a Python egg_ or are using eggs in your Django 312project, some extra configuration is required. Create an extra file in your 313project (or somewhere else) that contains something like the following: 314 315.. code-block:: python 316 317 import os 318 os.environ['PYTHON_EGG_CACHE'] = '/some/directory' 319 320Here, ``/some/directory`` is a directory that the Apache Web server process can 321write to. It will be used as the location for any unpacking of code the eggs 322need to do. 323 324Then you have to tell mod_python to import this file before doing anything 325else. This is done using the PythonImport_ directive to mod_python. You need 326to ensure that you have specified the ``PythonInterpreter`` directive to 327mod_python as described above__ (you need to do this even if you aren't 328serving multiple installations in this case). Then add the ``PythonImport`` 329line in the main server configuration (i.e., outside the ``Location`` or 330``VirtualHost`` sections). For example:: 331 332 PythonInterpreter my_django 333 PythonImport /path/to/my/project/file.py my_django 334 335Note that you can use an absolute path here (or a normal dotted import path), 336as described in the `mod_python manual`_. We use an absolute path in the 337above example because if any Python path modifications are required to access 338your project, they will not have been done at the time the ``PythonImport`` 339line is processed. 340 341.. _Egg: http://peak.telecommunity.com/DevCenter/PythonEggs 342.. _PythonImport: http://www.modpython.org/live/current/doc-html/dir-other-pimp.html 343.. _mod_python manual: PythonImport_ 344__ `Multiple Django installations on the same Apache`_ 345 346Error handling 347============== 348 349When you use Apache/mod_python, errors will be caught by Django -- in other 350words, they won't propagate to the Apache level and won't appear in the Apache 351``error_log``. 352 353The exception for this is if something is really wonky in your Django setup. In 354that case, you'll see an "Internal Server Error" page in your browser and the 355full Python traceback in your Apache ``error_log`` file. The ``error_log`` 356traceback is spread over multiple lines. (Yes, this is ugly and rather hard to 357read, but it's how mod_python does things.) 358 359If you get a segmentation fault 360=============================== 361 362If Apache causes a segmentation fault, there are two probable causes, neither 363of which has to do with Django itself. 364 365 1. It may be because your Python code is importing the "pyexpat" module, 366 which may conflict with the version embedded in Apache. For full 367 information, see `Expat Causing Apache Crash`_. 368 369 2. It may be because you're running mod_python and mod_php in the same 370 Apache instance, with MySQL as your database backend. In some cases, 371 this causes a known mod_python issue due to version conflicts in PHP and 372 the Python MySQL backend. There's full information in the 373 `mod_python FAQ entry`_. 374 375If you continue to have problems setting up mod_python, a good thing to do is 376get a barebones mod_python site working, without the Django framework. This is 377an easy way to isolate mod_python-specific problems. `Getting mod_python Working`_ 378details this procedure. 379 380The next step should be to edit your test code and add an import of any 381Django-specific code you're using -- your views, your models, your URLconf, 382your RSS configuration, etc. Put these imports in your test handler function 383and access your test URL in a browser. If this causes a crash, you've confirmed 384it's the importing of Django code that causes the problem. Gradually reduce the 385set of imports until it stops crashing, so as to find the specific module that 386causes the problem. Drop down further into modules and look into their imports, 387as necessary. 388 389.. _Expat Causing Apache Crash: http://www.dscpl.com.au/wiki/ModPython/Articles/ExpatCausingApacheCrash 390.. _mod_python FAQ entry: http://modpython.org/FAQ/faqw.py?req=show&file=faq02.013.htp 391.. _Getting mod_python Working: http://www.dscpl.com.au/wiki/ModPython/Articles/GettingModPythonWorking 392 393If you get a UnicodeEncodeError 394=============================== 395 396If you're taking advantage of the internationalization features of Django (see 397:doc:`/topics/i18n/index`) and you intend to allow users to upload files, you must 398ensure that the environment used to start Apache is configured to accept 399non-ASCII file names. If your environment is not correctly configured, you 400will trigger ``UnicodeEncodeError`` exceptions when calling functions like 401``os.path()`` on filenames that contain non-ASCII characters. 402 403To avoid these problems, the environment used to start Apache should contain 404settings analogous to the following:: 405 406 export LANG='en_US.UTF-8' 407 export LC_ALL='en_US.UTF-8' 408 409Consult the documentation for your operating system for the appropriate syntax 410and location to put these configuration items; ``/etc/apache2/envvars`` is a 411common location on Unix platforms. Once you have added these statements 412to your environment, restart Apache.