mirror of
				https://github.com/django/django.git
				synced 2025-10-29 00:26:07 +00:00 
			
		
		
		
	Fixes #8358, #8396, #8724, #9043, #9128, #9247, #9267, #9267, #9375, #9409, #9414, #9416, #9446, #9454, #9464, #9503, #9518, #9533, #9657, #9658, #9683, #9733, #9771, #9835, #9836, #9837, #9897, #9906, #9912, #9945, #9986, #9992, #10055, #10084, #10091, #10145, #10245, #10257, #10309, #10358, #10359, #10424, #10426, #10508, #10531, #10551, #10635, #10637, #10656, #10658, #10690, #10699, #19528. Thanks to all the respective authors of those tickets. git-svn-id: http://code.djangoproject.com/svn/django/trunk@10371 bcc190cf-cafb-0310-a4f2-bffc1f526a37
		
			
				
	
	
		
			177 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| .. _topics-http-middleware:
 | |
| 
 | |
| ==========
 | |
| Middleware
 | |
| ==========
 | |
| 
 | |
| Middleware is a framework of hooks into Django's request/response processing.
 | |
| It's a light, low-level "plugin" system for globally altering Django's input
 | |
| and/or output.
 | |
| 
 | |
| Each middleware component is responsible for doing some specific function. For
 | |
| example, Django includes a middleware component, ``XViewMiddleware``, that adds
 | |
| an ``"X-View"`` HTTP header to every response to a ``HEAD`` request.
 | |
| 
 | |
| This document explains how middleware works, how you activate middleware, and
 | |
| how to write your own middleware. Django ships with some built-in middleware
 | |
| you can use right out of the box; they're documented in the :ref:`built-in
 | |
| middleware reference <ref-middleware>`.
 | |
| 
 | |
| Activating middleware
 | |
| =====================
 | |
| 
 | |
| To activate a middleware component, add it to the :setting:`MIDDLEWARE_CLASSES`
 | |
| list in your Django settings. In :setting:`MIDDLEWARE_CLASSES`, each middleware
 | |
| component is represented by a string: the full Python path to the middleware's
 | |
| class name. For example, here's the default :setting:`MIDDLEWARE_CLASSES`
 | |
| created by :djadmin:`django-admin.py startproject <startproject>`::
 | |
| 
 | |
|     MIDDLEWARE_CLASSES = (
 | |
|         'django.middleware.common.CommonMiddleware',
 | |
|         'django.contrib.sessions.middleware.SessionMiddleware',
 | |
|         'django.contrib.auth.middleware.AuthenticationMiddleware',
 | |
|     )
 | |
| 
 | |
| During the request phases (:meth:`process_request` and :meth:`process_view`
 | |
| middleware), Django applies middleware in the order it's defined in
 | |
| :setting:`MIDDLEWARE_CLASSES`, top-down. During the response phases
 | |
| (:meth:`process_response` and :meth:`process_exception` middleware), the
 | |
| classes are applied in reverse order, from the bottom up. You can think of it
 | |
| like an onion: each middleware class is a "layer" that wraps the view:
 | |
| 
 | |
| .. image:: _images/middleware.png
 | |
|    :width: 502
 | |
|    :height: 417
 | |
|    :alt: Middleware application order.
 | |
| 
 | |
| A Django installation doesn't require any middleware -- e.g.,
 | |
| :setting:`MIDDLEWARE_CLASSES` can be empty, if you'd like -- but it's strongly
 | |
| suggested that you at least use
 | |
| :class:`~django.middleware.common.CommonMiddleware`.
 | |
| 
 | |
| Writing your own middleware
 | |
| ===========================
 | |
| 
 | |
| Writing your own middleware is easy. Each middleware component is a single
 | |
| Python class that defines one or more of the following methods:
 | |
| 
 | |
| .. _request-middleware:
 | |
| 
 | |
| ``process_request``
 | |
| -------------------
 | |
| 
 | |
| .. method:: process_request(self, request)
 | |
| 
 | |
| ``request`` is an :class:`~django.http.HttpRequest` object. This method is
 | |
| called on each request, before Django decides which view to execute.
 | |
| 
 | |
| ``process_request()`` should return either ``None`` or an
 | |
| :class:`~django.http.HttpResponse` object. If it returns ``None``, Django will
 | |
| continue processing this request, executing any other middleware and, then, the
 | |
| appropriate view. If it returns an :class:`~django.http.HttpResponse` object,
 | |
| Django won't bother calling ANY other request, view or exception middleware, or
 | |
| the appropriate view; it'll return that :class:`~django.http.HttpResponse`.
 | |
| Response middleware is always called on every response.
 | |
| 
 | |
| .. _view-middleware:
 | |
| 
 | |
| ``process_view``
 | |
| ----------------
 | |
| 
 | |
| .. method:: process_view(self, request, view_func, view_args, view_kwargs)
 | |
| 
 | |
| ``request`` is an :class:`~django.http.HttpRequest` object. ``view_func`` is
 | |
| the Python function that Django is about to use. (It's the actual function
 | |
| object, not the name of the function as a string.) ``view_args`` is a list of
 | |
| positional arguments that will be passed to the view, and ``view_kwargs`` is a
 | |
| dictionary of keyword arguments that will be passed to the view. Neither
 | |
| ``view_args`` nor ``view_kwargs`` include the first view argument
 | |
| (``request``).
 | |
| 
 | |
| ``process_view()`` is called just before Django calls the view. It should
 | |
| return either ``None`` or an :class:`~django.http. HttpResponse` object. If it
 | |
| returns ``None``, Django will continue processing this request, executing any
 | |
| other ``process_view()`` middleware and, then, the appropriate view. If it
 | |
| returns an :class:`~django.http. HttpResponse` object, Django won't bother
 | |
| calling ANY other request, view or exception middleware, or the appropriate
 | |
| view; it'll return that :class:`~django.http. HttpResponse`. Response
 | |
| middleware is always called on every response.
 | |
| 
 | |
| .. _response-middleware:
 | |
| 
 | |
| ``process_response``
 | |
| --------------------
 | |
| 
 | |
| .. method:: process_response(self, request, response)
 | |
| 
 | |
| ``request`` is an :class:`~django.http.HttpRequest` object. ``response`` is the
 | |
| :class:`~django.http. HttpResponse` object returned by a Django view.
 | |
| 
 | |
| ``process_response()`` should return an :class:`~django.http. HttpResponse`
 | |
| object. It could alter the given ``response``, or it could create and return a
 | |
| brand-new :class:`~django.http. HttpResponse`.
 | |
| 
 | |
| Remember that your middleware will not be called if another middleware object
 | |
| returns a response before you. But unlike ``process_request()`` and
 | |
| ``process_view()``, during the response phase the classes are applied in reverse
 | |
| order, from the bottom up. This means classes defined at the end of
 | |
| :setting:`MIDDLEWARE_CLASSES` will be run first.
 | |
| 
 | |
| .. _exception-middleware:
 | |
| 
 | |
| ``process_exception``
 | |
| ---------------------
 | |
| 
 | |
| .. method:: process_exception(self, request, exception)
 | |
| 
 | |
| ``request`` is an :class:`~django.http.HttpRequest` object. ``exception`` is an
 | |
| ``Exception`` object raised by the view function.
 | |
| 
 | |
| Django calls ``process_exception()`` when a view raises an exception.
 | |
| ``process_exception()`` should return either ``None`` or an
 | |
| :class:`~django.http. HttpResponse` object. If it returns an
 | |
| :class:`~django.http. HttpResponse` object, the response will be returned to
 | |
| the browser. Otherwise, default exception handling kicks in.
 | |
| 
 | |
| Again, middleware are run in reverse order during the response phase, which
 | |
| includes ``process_exception``. If an exception middleware return a response,
 | |
| the middleware classes above that middleware will not be called at all.
 | |
| 
 | |
| ``__init__``
 | |
| ------------
 | |
| 
 | |
| Most middleware classes won't need an initializer since middleware classes are
 | |
| essentially placeholders for the ``process_*`` methods. If you do need some
 | |
| global state you may use ``__init__`` to set up. However, keep in mind a couple
 | |
| of caveats:
 | |
| 
 | |
|     * Django initializes your middleware without any arguments, so you can't
 | |
|       define ``__init__`` as requiring any arguments.
 | |
| 
 | |
|     * Unlike the ``process_*`` methods which get called once per request,
 | |
|       ``__init__`` gets called only *once*, when the web server starts up.
 | |
| 
 | |
| Marking middleware as unused
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| It's sometimes useful to determine at run-time whether a piece of middleware
 | |
| should be used. In these cases, your middleware's ``__init__`` method may raise
 | |
| ``django.core.exceptions.MiddlewareNotUsed``. Django will then remove that
 | |
| piece of middleware from the middleware process.
 | |
| 
 | |
| Guidelines
 | |
| ----------
 | |
| 
 | |
|     * Middleware classes don't have to subclass anything.
 | |
| 
 | |
|     * The middleware class can live anywhere on your Python path. All Django
 | |
|       cares about is that the :setting:`MIDDLEWARE_CLASSES` setting includes
 | |
|       the path to it.
 | |
| 
 | |
|     * Feel free to look at :ref:`Django's available middleware
 | |
|       <ref-middleware>` for examples.
 | |
| 
 | |
|     * If you write a middleware component that you think would be useful to
 | |
|       other people, contribute to the community! :ref:`Let us know
 | |
|       <internals-contributing>`, and we'll consider adding it to Django.
 |