diff --git a/django/core/cache/__init__.py b/django/core/cache/__init__.py
index 9eac8ec8fe..d8095d4e51 100644
--- a/django/core/cache/__init__.py
+++ b/django/core/cache/__init__.py
@@ -14,6 +14,8 @@ cache class.
See docs/topics/cache.txt for information on the public API.
"""
+from urlparse import parse_qsl
+
from django.conf import settings
from django.core import signals
from django.core.cache.backends.base import (
@@ -21,12 +23,6 @@ from django.core.cache.backends.base import (
from django.core.exceptions import ImproperlyConfigured
from django.utils import importlib
-try:
- # The mod_python version is more efficient, so try importing it first.
- from mod_python.util import parse_qsl
-except ImportError:
- from urlparse import parse_qsl
-
__all__ = [
'get_cache', 'cache', 'DEFAULT_CACHE_ALIAS'
]
diff --git a/django/http/__init__.py b/django/http/__init__.py
index 5f407a4403..2f3392f449 100644
--- a/django/http/__init__.py
+++ b/django/http/__init__.py
@@ -9,16 +9,11 @@ import warnings
from pprint import pformat
from urllib import urlencode, quote
-from urlparse import urljoin
+from urlparse import urljoin, parse_qsl
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
-try:
- # The mod_python version is more efficient, so try importing it first.
- from mod_python.util import parse_qsl
-except ImportError:
- from urlparse import parse_qsl
import Cookie
# Some versions of Python 2.7 and later won't need this encoding bug fix:
@@ -348,7 +343,7 @@ class HttpRequest(object):
## File-like and iterator interface.
##
## Expects self._stream to be set to an appropriate source of bytes by
- ## a corresponding request subclass (WSGIRequest or ModPythonRequest).
+ ## a corresponding request subclass (e.g. WSGIRequest).
## Also when request data has already been read by request.POST or
## request.body, self._stream points to a StringIO instance
## containing that data.
diff --git a/docs/faq/usage.txt b/docs/faq/usage.txt
index 2b185be1a6..151454398d 100644
--- a/docs/faq/usage.txt
+++ b/docs/faq/usage.txt
@@ -13,15 +13,6 @@ Make sure that:
* The module doesn't contain syntax errors (of course).
-* If you're using mod_python but *not* using Django's request handler,
- you'll need to work around a mod_python bug related to the use of
- ``SetEnv``; before you import anything from Django you'll need to do
- the following::
-
- os.environ.update(req.subprocess_env)
-
- (where ``req`` is the mod_python request object).
-
I can't stand your template language. Do I have to use it?
----------------------------------------------------------
diff --git a/docs/howto/apache-auth.txt b/docs/howto/apache-auth.txt
index 215c519238..719fbc1769 100644
--- a/docs/howto/apache-auth.txt
+++ b/docs/howto/apache-auth.txt
@@ -2,17 +2,10 @@
Authenticating against Django's user database from Apache
=========================================================
-.. warning::
-
- Support for mod_python has been deprecated within Django. At that
- time, this method of authentication will no longer be provided by
- Django. The community is welcome to offer its own alternate
- solutions using WSGI middleware or other approaches.
-
Since keeping multiple authentication databases in sync is a common problem when
dealing with Apache, you can configuring Apache to authenticate against Django's
-:doc:`authentication system ` directly. For example, you
-could:
+:doc:`authentication system ` directly. This requires Apache
+version >= 2.2 and mod_wsgi >= 2.0. For example, you could:
* Serve static/media files directly from Apache only to authenticated users.
@@ -22,106 +15,31 @@ could:
* Allow certain users to connect to a WebDAV share created with mod_dav_.
.. _Subversion: http://subversion.tigris.org/
-.. _mod_dav: http://httpd.apache.org/docs/2.0/mod/mod_dav.html
+.. _mod_dav: http://httpd.apache.org/docs/2.2/mod/mod_dav.html
Configuring Apache
==================
To check against Django's authorization database from a Apache configuration
-file, you'll need to use mod_python's ``PythonAuthenHandler`` directive along
-with the standard ``Auth*`` and ``Require`` directives:
+file, you'll need to set 'wsgi' as the value of ``AuthBasicProvider`` or
+``AuthDigestProvider`` directive and then use the ``WSGIAuthUserScript``
+directive to set the path to your authentification script:
.. code-block:: apache
AuthType Basic
AuthName "example.com"
+ AuthBasicProvider wsgi
+ WSGIAuthUserScript /usr/local/wsgi/scripts/auth.wsgi
Require valid-user
-
- SetEnv DJANGO_SETTINGS_MODULE mysite.settings
- PythonAuthenHandler django.contrib.auth.handlers.modpython
-.. admonition:: Using the authentication handler with Apache 2.2
+Your auth.wsgi script will have to implement either a
+``check_password(environ, user, password)`` function (for ``AuthBasicProvider``)
+or a ``get_realm_hash(environ, user, realm)`` function (for ``AuthDigestProvider``).
- If you're using Apache 2.2, you'll need to take a couple extra steps.
+See the `mod_wsgi documentation`_ for more details about the implementation
+of such a solution.
- You'll need to ensure that ``mod_auth_basic`` and ``mod_authz_user``
- are loaded. These might be compiled statically into Apache, or you might
- need to use ``LoadModule`` to load them dynamically (as shown in the
- example at the bottom of this note).
-
- You'll also need to insert configuration directives that prevent Apache
- from trying to use other authentication modules, as well as specifying
- the ``AuthUserFile`` directive and pointing it to ``/dev/null``. Depending
- on which other authentication modules you have loaded, you might need one
- or more of the following directives:
-
- .. code-block:: apache
-
- AuthBasicAuthoritative Off
- AuthDefaultAuthoritative Off
- AuthzLDAPAuthoritative Off
- AuthzDBMAuthoritative Off
- AuthzDefaultAuthoritative Off
- AuthzGroupFileAuthoritative Off
- AuthzOwnerAuthoritative Off
- AuthzUserAuthoritative Off
-
- A complete configuration, with differences between Apache 2.0 and
- Apache 2.2 marked in bold, would look something like:
-
- .. parsed-literal::
-
- **LoadModule auth_basic_module modules/mod_auth_basic.so**
- **LoadModule authz_user_module modules/mod_authz_user.so**
-
- ...
-
-
- AuthType Basic
- AuthName "example.com"
- **AuthUserFile /dev/null**
- **AuthBasicAuthoritative Off**
- Require valid-user
-
- SetEnv DJANGO_SETTINGS_MODULE mysite.settings
- PythonAuthenHandler django.contrib.auth.handlers.modpython
-
-
-By default, the authentication handler will limit access to the ``/example/``
-location to users marked as staff members. You can use a set of
-``PythonOption`` directives to modify this behavior:
-
-================================ =========================================
-``PythonOption`` Explanation
-================================ =========================================
-``DjangoRequireStaffStatus`` If set to ``on`` only "staff" users (i.e.
- those with the ``is_staff`` flag set)
- will be allowed.
-
- Defaults to ``on``.
-
-``DjangoRequireSuperuserStatus`` If set to ``on`` only superusers (i.e.
- those with the ``is_superuser`` flag set)
- will be allowed.
-
- Defaults to ``off``.
-
-``DjangoPermissionName`` The name of a permission to require for
- access. See :ref:`custom permissions
- ` for more
- information.
-
- By default no specific permission will be
- required.
-================================ =========================================
-
-Note that sometimes ``SetEnv`` doesn't play well in this mod_python
-configuration, for reasons unknown. If you're having problems getting
-mod_python to recognize your ``DJANGO_SETTINGS_MODULE``, you can set it using
-``PythonOption`` instead of ``SetEnv``. Therefore, these two Apache directives
-are equivalent::
-
- SetEnv DJANGO_SETTINGS_MODULE mysite.settings
- PythonOption DJANGO_SETTINGS_MODULE mysite.settings
+.. _mod_wsgi documentation: http://code.google.com/p/modwsgi/wiki/AccessControlMechanisms#Apache_Authentication_Provider
diff --git a/docs/howto/deployment/index.txt b/docs/howto/deployment/index.txt
index 113f6067fb..8e27a031d5 100644
--- a/docs/howto/deployment/index.txt
+++ b/docs/howto/deployment/index.txt
@@ -11,7 +11,6 @@ ways to easily deploy Django:
wsgi/index
fastcgi
- mod_python (deprecated)
If you're new to deploying Django and/or Python, we'd recommend you try
:doc:`mod_wsgi ` first. In most cases it'll be
@@ -22,6 +21,6 @@ the easiest, fastest, and most stable deployment choice.
* `Chapter 12 of the Django Book (second edition)`_ discusses deployment
and especially scaling in more detail. However, note that this edition
was written against Django version 1.1 and has not been updated since
- :doc:`mod_python ` was deprecated.
+ `mod_python` was first deprecated, then completely removed in Django 1.5.
.. _chapter 12 of the django book (second edition): http://djangobook.com/en/2.0/chapter12/
diff --git a/docs/howto/deployment/wsgi/modwsgi.txt b/docs/howto/deployment/wsgi/modwsgi.txt
index 1aa4009697..8398f12eb7 100644
--- a/docs/howto/deployment/wsgi/modwsgi.txt
+++ b/docs/howto/deployment/wsgi/modwsgi.txt
@@ -176,3 +176,24 @@ other approaches:
3. Copy the admin static files so that they live within your Apache
document root.
+
+If you get a UnicodeEncodeError
+===============================
+
+If you're taking advantage of the internationalization features of Django (see
+:doc:`/topics/i18n/index`) and you intend to allow users to upload files, you must
+ensure that the environment used to start Apache is configured to accept
+non-ASCII file names. If your environment is not correctly configured, you
+will trigger ``UnicodeEncodeError`` exceptions when calling functions like
+``os.path()`` on filenames that contain non-ASCII characters.
+
+To avoid these problems, the environment used to start Apache should contain
+settings analogous to the following::
+
+ export LANG='en_US.UTF-8'
+ export LC_ALL='en_US.UTF-8'
+
+Consult the documentation for your operating system for the appropriate syntax
+and location to put these configuration items; ``/etc/apache2/envvars`` is a
+common location on Unix platforms. Once you have added these statements
+to your environment, restart Apache.
diff --git a/docs/index.txt b/docs/index.txt
index a5d2e139ac..66c8e73a0c 100644
--- a/docs/index.txt
+++ b/docs/index.txt
@@ -156,7 +156,6 @@ The development process
:doc:`Overview ` |
:doc:`WSGI servers ` |
:doc:`FastCGI/SCGI/AJP ` |
- :doc:`Apache/mod_python (deprecated) ` |
:doc:`Apache authentication ` |
:doc:`Handling static files ` |
:doc:`Tracking code errors by email `
diff --git a/docs/ref/contrib/gis/deployment.txt b/docs/ref/contrib/gis/deployment.txt
index c50a3782dc..d98fc51837 100644
--- a/docs/ref/contrib/gis/deployment.txt
+++ b/docs/ref/contrib/gis/deployment.txt
@@ -13,11 +13,9 @@ Deploying GeoDjango
Apache
======
In this section there are some example ``VirtualHost`` directives for
-when deploying using either ``mod_python`` or ``mod_wsgi``. At this
-time, we recommend ``mod_wsgi``, as it is now officially recommended
-way to deploy Django applications with Apache. Moreover, if
-``mod_python`` is used, then a prefork version of Apache must also be
-used. As long as ``mod_wsgi`` is configured correctly, it does not
+when deploying using ``mod_wsgi``, which is now officially the recommended
+way to deploy Django applications with Apache.
+As long as ``mod_wsgi`` is configured correctly, it does not
matter whether the version of Apache is prefork or worker.
.. note::
@@ -56,42 +54,6 @@ Example::
For more information, please consult Django's
:doc:`mod_wsgi documentation `.
-``mod_python``
---------------
-
-.. warning::
- Support for mod_python will be deprecated in a future release of Django. If
- you are configuring a new deployment, you are strongly encouraged to
- consider using :doc:`mod_wsgi ` or any of
- the other :doc:`supported servers `.
-
-Example::
-
-
-
-
- SetHandler mod_python
- PythonHandler django.core.handlers.modpython
- SetEnv DJANGO_SETTINGS_MODULE world.settings
- PythonDebug On
- PythonPath "['/var/www/apps'] + sys.path"
-
-
- Alias /media/ "/usr/lib/python2.6/site-packages/django/contrib/admin/media/"
-
- SetHandler None
-
-
-
-
-.. warning::
-
- When using ``mod_python`` you *must* be using a prefork version of Apache, or
- else your GeoDjango application may crash Apache.
-
-For more information, please consult Django's
-:doc:`mod_python documentation `.
-
Lighttpd
========
diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt
index c0ae73e1db..ae736b1c75 100644
--- a/docs/ref/request-response.txt
+++ b/docs/ref/request-response.txt
@@ -56,15 +56,13 @@ All attributes except ``session`` should be considered read-only.
.. attribute:: HttpRequest.path_info
Under some Web server configurations, the portion of the URL after the host
- name is split up into a script prefix portion and a path info portion
- (this happens, for example, when using the ``django.root`` option
- with the :doc:`modpython handler from Apache `).
+ name is split up into a script prefix portion and a path info portion.
The ``path_info`` attribute always contains the path info portion of the
path, no matter what Web server is being used. Using this instead of
attr:`~HttpRequest.path` can make your code much easier to move between test
and deployment servers.
- For example, if the ``django.root`` for your application is set to
+ For example, if the ``WSGIScriptAlias`` for your application is set to
``"/minfo"``, then ``path`` might be ``"/minfo/music/bands/the_beatles/"``
and ``path_info`` would be ``"/music/bands/the_beatles/"``.
diff --git a/docs/topics/http/urls.txt b/docs/topics/http/urls.txt
index 1c2849d477..73c06ca2ae 100644
--- a/docs/topics/http/urls.txt
+++ b/docs/topics/http/urls.txt
@@ -1020,6 +1020,4 @@ find the base URL of the Django project within its Web server
(normally, :func:`~django.core.urlresolvers.reverse` takes care of this for
you). In that case, you can call ``get_script_prefix()``, which will return the
script prefix portion of the URL for your Django project. If your Django
-project is at the root of its Web server, this is always ``"/"``, but it can be
-changed, for instance by using ``django.root`` (see :doc:`How to use
-Django with Apache and mod_python `).
+project is at the root of its Web server, this is always ``"/"``.
diff --git a/tests/regressiontests/requests/tests.py b/tests/regressiontests/requests/tests.py
index f986046b5d..5c3cf59eaf 100644
--- a/tests/regressiontests/requests/tests.py
+++ b/tests/regressiontests/requests/tests.py
@@ -4,7 +4,6 @@ from datetime import datetime, timedelta
from StringIO import StringIO
from django.conf import settings
-from django.core.handlers.modpython import ModPythonRequest
from django.core.handlers.wsgi import WSGIRequest, LimitedStream
from django.http import HttpRequest, HttpResponse, parse_cookie, build_request_repr, UnreadablePostError
from django.test.utils import get_warnings_state, restore_warnings_state
@@ -54,41 +53,6 @@ class RequestsTests(unittest.TestCase):
self.assertEqual(build_request_repr(request, path_override='/otherpath/', GET_override={u'a': u'b'}, POST_override={u'c': u'd'}, COOKIES_override={u'e': u'f'}, META_override={u'g': u'h'}),
u"")
- def test_modpythonrequest(self):
- class FakeModPythonRequest(ModPythonRequest):
- def __init__(self, *args, **kwargs):
- super(FakeModPythonRequest, self).__init__(*args, **kwargs)
- self._get = self._post = self._meta = self._cookies = {}
-
- class Dummy:
- def get_options(self):
- return {}
-
- req = Dummy()
- req.uri = 'bogus'
- request = FakeModPythonRequest(req)
- self.assertEqual(request.path, 'bogus')
- self.assertEqual(request.GET.keys(), [])
- self.assertEqual(request.POST.keys(), [])
- self.assertEqual(request.COOKIES.keys(), [])
- self.assertEqual(request.META.keys(), [])
-
- def test_modpythonrequest_repr(self):
- class Dummy:
- def get_options(self):
- return {}
- req = Dummy()
- req.uri = '/somepath/'
- request = ModPythonRequest(req)
- request._get = {u'get-key': u'get-value'}
- request._post = {u'post-key': u'post-value'}
- request._cookies = {u'post-key': u'post-value'}
- request._meta = {u'post-key': u'post-value'}
- self.assertEqual(repr(request), u"")
- self.assertEqual(build_request_repr(request), repr(request))
- self.assertEqual(build_request_repr(request, path_override='/otherpath/', GET_override={u'a': u'b'}, POST_override={u'c': u'd'}, COOKIES_override={u'e': u'f'}, META_override={u'g': u'h'}),
- u"")
-
def test_parse_cookie(self):
self.assertEqual(parse_cookie('invalid:key=true'), {})