1
0
mirror of https://github.com/django/django.git synced 2025-10-24 06:06:09 +00:00

Fixed #26601 -- Improved middleware per DEP 0005.

Thanks Tim Graham for polishing the patch, updating the tests, and
writing documentation. Thanks Carl Meyer for shepherding the DEP.
This commit is contained in:
Florian Apolloner
2015-11-07 16:12:37 +01:00
committed by Tim Graham
parent 05c888ffb8
commit 9baf692a58
81 changed files with 900 additions and 1414 deletions

View File

@@ -1,957 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ActiveLayerIndex</key>
<integer>0</integer>
<key>ApplicationVersion</key>
<array>
<string>com.omnigroup.OmniGrafflePro</string>
<string>139.16.0.171715</string>
</array>
<key>AutoAdjust</key>
<true/>
<key>BackgroundGraphic</key>
<dict>
<key>Bounds</key>
<string>{{0, 0}, {559.28997802734375, 782.8900146484375}}</string>
<key>Class</key>
<string>SolidGraphic</string>
<key>ID</key>
<integer>2</integer>
<key>Style</key>
<dict>
<key>shadow</key>
<dict>
<key>Draws</key>
<string>NO</string>
</dict>
<key>stroke</key>
<dict>
<key>Draws</key>
<string>NO</string>
</dict>
</dict>
</dict>
<key>BaseZoom</key>
<integer>0</integer>
<key>CanvasOrigin</key>
<string>{0, 0}</string>
<key>ColumnAlign</key>
<integer>1</integer>
<key>ColumnSpacing</key>
<real>36</real>
<key>CreationDate</key>
<string>2012-12-09 18:55:12 +0000</string>
<key>Creator</key>
<string>Aymeric Augustin</string>
<key>DisplayScale</key>
<string>1.000 cm = 1.000 cm</string>
<key>GraphDocumentVersion</key>
<integer>8</integer>
<key>GraphicsList</key>
<array>
<dict>
<key>Bounds</key>
<string>{{144, 405}, {369, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>33</integer>
<key>Shape</key>
<string>Bezier</string>
<key>ShapeData</key>
<dict>
<key>UnitPoints</key>
<array>
<string>{-0.5, -0.5}</string>
<string>{-0.5, -0.5}</string>
<string>{0.47959183673469341, -0.5}</string>
<string>{0.47959183673469408, -0.5}</string>
<string>{0.47959183673469341, -0.5}</string>
<string>{0.5, 0}</string>
<string>{0.5, 0}</string>
<string>{0.5, 0}</string>
<string>{0.47959183673469408, 0.5}</string>
<string>{0.47959183673469408, 0.5}</string>
<string>{0.47959183673469408, 0.5}</string>
<string>{-0.5, 0.5}</string>
<string>{-0.5, 0.5}</string>
<string>{-0.5, 0.5}</string>
<string>{-0.47560975609756084, 0}</string>
<string>{-0.47560975609756084, 0}</string>
<string>{-0.47560975609756084, 0}</string>
<string>{-0.5, -0.5}</string>
</array>
</dict>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
\f0\fs24 \cf0 view function}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{229.5, 238.5}, {297, 36}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>31</integer>
<key>Rotation</key>
<real>270</real>
<key>Shape</key>
<string>AdjustableArrow</string>
<key>ShapeData</key>
<dict>
<key>width</key>
<real>27</real>
</dict>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>Color</key>
<dict>
<key>a</key>
<string>0.8</string>
<key>b</key>
<string>1</string>
<key>g</key>
<string>1</string>
<key>r</key>
<string>1</string>
</dict>
<key>MiddleFraction</key>
<real>0.70634919404983521</real>
</dict>
<key>shadow</key>
<dict>
<key>Color</key>
<dict>
<key>a</key>
<string>0.4</string>
<key>b</key>
<string>0</string>
<key>g</key>
<string>0</string>
<key>r</key>
<string>0</string>
</dict>
<key>Draws</key>
<string>NO</string>
<key>Fuzziness</key>
<real>0.0</real>
<key>ShadowVector</key>
<string>{0, 2}</string>
</dict>
<key>stroke</key>
<dict>
<key>Color</key>
<dict>
<key>b</key>
<string>0</string>
<key>g</key>
<string>0</string>
<key>r</key>
<string>1</string>
</dict>
<key>Pattern</key>
<integer>1</integer>
</dict>
</dict>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;\red255\green0\blue0;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
\f0\fs24 \cf2 process_exception}</string>
</dict>
<key>TextRelativeArea</key>
<string>{{0.125, 0.25}, {0.75, 0.5}}</string>
<key>isConnectedShape</key>
<true/>
</dict>
<dict>
<key>Bounds</key>
<string>{{328.5, 229.5}, {315, 36}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>30</integer>
<key>Rotation</key>
<real>270</real>
<key>Shape</key>
<string>AdjustableArrow</string>
<key>ShapeData</key>
<dict>
<key>width</key>
<real>27</real>
</dict>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>Color</key>
<dict>
<key>a</key>
<string>0.8</string>
<key>b</key>
<string>1</string>
<key>g</key>
<string>1</string>
<key>r</key>
<string>1</string>
</dict>
<key>MiddleFraction</key>
<real>0.70634919404983521</real>
</dict>
<key>shadow</key>
<dict>
<key>Color</key>
<dict>
<key>a</key>
<string>0.4</string>
<key>b</key>
<string>0</string>
<key>g</key>
<string>0</string>
<key>r</key>
<string>0</string>
</dict>
<key>Draws</key>
<string>NO</string>
<key>Fuzziness</key>
<real>0.0</real>
<key>ShadowVector</key>
<string>{0, 2}</string>
</dict>
<key>stroke</key>
<dict>
<key>Color</key>
<dict>
<key>b</key>
<string>0</string>
<key>g</key>
<string>0.501961</string>
<key>r</key>
<string>0</string>
</dict>
</dict>
</dict>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;\red0\green128\blue0;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
\f0\fs24 \cf2 process_response}</string>
</dict>
<key>TextRelativeArea</key>
<string>{{0.125, 0.25}, {0.75, 0.5}}</string>
<key>isConnectedShape</key>
<true/>
</dict>
<dict>
<key>Bounds</key>
<string>{{283.5, 238.5}, {297, 36}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>29</integer>
<key>Rotation</key>
<real>270</real>
<key>Shape</key>
<string>AdjustableArrow</string>
<key>ShapeData</key>
<dict>
<key>width</key>
<real>27</real>
</dict>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>Color</key>
<dict>
<key>a</key>
<string>0.8</string>
<key>b</key>
<string>1</string>
<key>g</key>
<string>1</string>
<key>r</key>
<string>1</string>
</dict>
<key>MiddleFraction</key>
<real>0.70634919404983521</real>
</dict>
<key>shadow</key>
<dict>
<key>Color</key>
<dict>
<key>a</key>
<string>0.4</string>
<key>b</key>
<string>0</string>
<key>g</key>
<string>0</string>
<key>r</key>
<string>0</string>
</dict>
<key>Draws</key>
<string>NO</string>
<key>Fuzziness</key>
<real>0.0</real>
<key>ShadowVector</key>
<string>{0, 2}</string>
</dict>
<key>stroke</key>
<dict>
<key>Color</key>
<dict>
<key>b</key>
<string>0</string>
<key>g</key>
<string>0.501961</string>
<key>r</key>
<string>0</string>
</dict>
<key>Pattern</key>
<integer>1</integer>
</dict>
</dict>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;\red0\green128\blue0;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
\f0\fs24 \cf2 process_template_response}</string>
</dict>
<key>TextRelativeArea</key>
<string>{{0.125, 0.25}, {0.75, 0.5}}</string>
<key>isConnectedShape</key>
<true/>
</dict>
<dict>
<key>Bounds</key>
<string>{{27, 243}, {288, 36}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>28</integer>
<key>Rotation</key>
<real>90</real>
<key>Shape</key>
<string>AdjustableArrow</string>
<key>ShapeData</key>
<dict>
<key>width</key>
<real>27</real>
</dict>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>Color</key>
<dict>
<key>a</key>
<string>0.8</string>
<key>b</key>
<string>1</string>
<key>g</key>
<string>1</string>
<key>r</key>
<string>1</string>
</dict>
<key>MiddleFraction</key>
<real>0.70634919404983521</real>
</dict>
<key>shadow</key>
<dict>
<key>Color</key>
<dict>
<key>a</key>
<string>0.4</string>
<key>b</key>
<string>0</string>
<key>g</key>
<string>0</string>
<key>r</key>
<string>0</string>
</dict>
<key>Draws</key>
<string>NO</string>
<key>Fuzziness</key>
<real>0.0</real>
<key>ShadowVector</key>
<string>{0, 2}</string>
</dict>
<key>stroke</key>
<dict>
<key>Color</key>
<dict>
<key>b</key>
<string>0</string>
<key>g</key>
<string>0.501961</string>
<key>r</key>
<string>0</string>
</dict>
</dict>
</dict>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;\red0\green128\blue0;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
\f0\fs24 \cf2 process_view}</string>
</dict>
<key>TextRelativeArea</key>
<string>{{0.125, 0.25}, {0.75, 0.5}}</string>
<key>isConnectedShape</key>
<true/>
</dict>
<dict>
<key>Bounds</key>
<string>{{-40.500000000767386, 220.49999999804004}, {297, 36}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>27</integer>
<key>Rotation</key>
<real>90</real>
<key>Shape</key>
<string>AdjustableArrow</string>
<key>ShapeData</key>
<dict>
<key>width</key>
<real>27</real>
</dict>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>Color</key>
<dict>
<key>a</key>
<string>0.8</string>
<key>b</key>
<string>1</string>
<key>g</key>
<string>1</string>
<key>r</key>
<string>1</string>
</dict>
<key>MiddleFraction</key>
<real>0.70634919404983521</real>
</dict>
<key>shadow</key>
<dict>
<key>Color</key>
<dict>
<key>a</key>
<string>0.4</string>
<key>b</key>
<string>0</string>
<key>g</key>
<string>0</string>
<key>r</key>
<string>0</string>
</dict>
<key>Draws</key>
<string>NO</string>
<key>Fuzziness</key>
<real>0.0</real>
<key>ShadowVector</key>
<string>{0, 2}</string>
</dict>
<key>stroke</key>
<dict>
<key>Color</key>
<dict>
<key>b</key>
<string>0</string>
<key>g</key>
<string>0.501961</string>
<key>r</key>
<string>0</string>
</dict>
</dict>
</dict>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;\red0\green128\blue0;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
\f0\fs24 \cf2 process_request}</string>
</dict>
<key>TextRelativeArea</key>
<string>{{0.125, 0.25}, {0.75, 0.5}}</string>
<key>isConnectedShape</key>
<true/>
</dict>
<dict>
<key>Bounds</key>
<string>{{360, 63}, {144, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>12</integer>
<key>Magnets</key>
<array>
<string>{0, 1}</string>
<string>{0, -1}</string>
<string>{1, 0}</string>
<string>{-1, 0}</string>
</array>
<key>Shape</key>
<string>Rectangle</string>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
\f0\fs24 \cf0 HttpResponse}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{72, 63}, {144, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>11</integer>
<key>Magnets</key>
<array>
<string>{0, 1}</string>
<string>{0, -1}</string>
<string>{1, 0}</string>
<string>{-1, 0}</string>
</array>
<key>Shape</key>
<string>Rectangle</string>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
\f0\fs24 \cf0 HttpRequest}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{72, 324}, {432, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>10</integer>
<key>Magnets</key>
<array>
<string>{0, 1}</string>
<string>{0, -1}</string>
<string>{1, 0}</string>
<string>{-1, 0}</string>
</array>
<key>Shape</key>
<string>Rectangle</string>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>FillType</key>
<integer>2</integer>
<key>GradientAngle</key>
<real>90</real>
<key>GradientColor</key>
<dict>
<key>w</key>
<string>0.666667</string>
</dict>
</dict>
<key>stroke</key>
<dict>
<key>CornerRadius</key>
<real>5</real>
</dict>
</dict>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
\f0\fs24 \cf0 MessageMiddleware}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{72, 279}, {432, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>9</integer>
<key>Magnets</key>
<array>
<string>{0, 1}</string>
<string>{0, -1}</string>
<string>{1, 0}</string>
<string>{-1, 0}</string>
</array>
<key>Shape</key>
<string>Rectangle</string>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>FillType</key>
<integer>2</integer>
<key>GradientAngle</key>
<real>90</real>
<key>GradientColor</key>
<dict>
<key>w</key>
<string>0.666667</string>
</dict>
</dict>
<key>stroke</key>
<dict>
<key>CornerRadius</key>
<real>5</real>
</dict>
</dict>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
\f0\fs24 \cf0 AuthenticationMiddleware}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{72, 234}, {432, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>8</integer>
<key>Magnets</key>
<array>
<string>{0, 1}</string>
<string>{0, -1}</string>
<string>{1, 0}</string>
<string>{-1, 0}</string>
</array>
<key>Shape</key>
<string>Rectangle</string>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>FillType</key>
<integer>2</integer>
<key>GradientAngle</key>
<real>90</real>
<key>GradientColor</key>
<dict>
<key>w</key>
<string>0.666667</string>
</dict>
</dict>
<key>stroke</key>
<dict>
<key>CornerRadius</key>
<real>5</real>
</dict>
</dict>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
\f0\fs24 \cf0 CsrfViewMiddleware}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{72, 189}, {432, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>7</integer>
<key>Magnets</key>
<array>
<string>{0, 1}</string>
<string>{0, -1}</string>
<string>{1, 0}</string>
<string>{-1, 0}</string>
</array>
<key>Shape</key>
<string>Rectangle</string>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>FillType</key>
<integer>2</integer>
<key>GradientAngle</key>
<real>90</real>
<key>GradientColor</key>
<dict>
<key>w</key>
<string>0.666667</string>
</dict>
</dict>
<key>stroke</key>
<dict>
<key>CornerRadius</key>
<real>5</real>
</dict>
</dict>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
\f0\fs24 \cf0 SessionMiddleware}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{72, 144}, {432, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>6</integer>
<key>Magnets</key>
<array>
<string>{0, 1}</string>
<string>{0, -1}</string>
<string>{1, 0}</string>
<string>{-1, 0}</string>
</array>
<key>Shape</key>
<string>Rectangle</string>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>FillType</key>
<integer>2</integer>
<key>GradientAngle</key>
<real>90</real>
<key>GradientColor</key>
<dict>
<key>w</key>
<string>0.666667</string>
</dict>
</dict>
<key>stroke</key>
<dict>
<key>CornerRadius</key>
<real>5</real>
</dict>
</dict>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
\f0\fs24 \cf0 CommonMiddleware}</string>
</dict>
</dict>
</array>
<key>GridInfo</key>
<dict>
<key>ShowsGrid</key>
<string>YES</string>
<key>SnapsToGrid</key>
<string>YES</string>
</dict>
<key>GuidesLocked</key>
<string>NO</string>
<key>GuidesVisible</key>
<string>YES</string>
<key>HPages</key>
<integer>1</integer>
<key>ImageCounter</key>
<integer>1</integer>
<key>KeepToScale</key>
<false/>
<key>Layers</key>
<array>
<dict>
<key>Lock</key>
<string>NO</string>
<key>Name</key>
<string>Calque 1</string>
<key>Print</key>
<string>YES</string>
<key>View</key>
<string>YES</string>
</dict>
</array>
<key>LayoutInfo</key>
<dict>
<key>Animate</key>
<string>NO</string>
<key>circoMinDist</key>
<real>18</real>
<key>circoSeparation</key>
<real>0.0</real>
<key>layoutEngine</key>
<string>dot</string>
<key>neatoSeparation</key>
<real>0.0</real>
<key>twopiSeparation</key>
<real>0.0</real>
</dict>
<key>LinksVisible</key>
<string>NO</string>
<key>MagnetsVisible</key>
<string>NO</string>
<key>MasterSheets</key>
<array/>
<key>ModificationDate</key>
<string>2012-12-09 19:48:54 +0000</string>
<key>Modifier</key>
<string>Aymeric Augustin</string>
<key>NotesVisible</key>
<string>NO</string>
<key>Orientation</key>
<integer>2</integer>
<key>OriginVisible</key>
<string>NO</string>
<key>PageBreaks</key>
<string>YES</string>
<key>PrintInfo</key>
<dict>
<key>NSBottomMargin</key>
<array>
<string>float</string>
<string>41</string>
</array>
<key>NSHorizonalPagination</key>
<array>
<string>coded</string>
<string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG</string>
</array>
<key>NSLeftMargin</key>
<array>
<string>float</string>
<string>18</string>
</array>
<key>NSPaperSize</key>
<array>
<string>size</string>
<string>{595.28997802734375, 841.8900146484375}</string>
</array>
<key>NSPrintReverseOrientation</key>
<array>
<string>int</string>
<string>0</string>
</array>
<key>NSRightMargin</key>
<array>
<string>float</string>
<string>18</string>
</array>
<key>NSTopMargin</key>
<array>
<string>float</string>
<string>18</string>
</array>
</dict>
<key>PrintOnePage</key>
<false/>
<key>ReadOnly</key>
<string>NO</string>
<key>RowAlign</key>
<integer>1</integer>
<key>RowSpacing</key>
<real>36</real>
<key>SheetTitle</key>
<string>Canevas 1</string>
<key>SmartAlignmentGuidesActive</key>
<string>YES</string>
<key>SmartDistanceGuidesActive</key>
<string>YES</string>
<key>UniqueID</key>
<integer>1</integer>
<key>UseEntirePage</key>
<false/>
<key>VPages</key>
<integer>1</integer>
<key>WindowInfo</key>
<dict>
<key>CurrentSheet</key>
<integer>0</integer>
<key>ExpandedCanvases</key>
<array/>
<key>Frame</key>
<string>{{248, 4}, {694, 874}}</string>
<key>ListView</key>
<true/>
<key>OutlineWidth</key>
<integer>142</integer>
<key>RightSidebar</key>
<false/>
<key>ShowRuler</key>
<true/>
<key>Sidebar</key>
<true/>
<key>SidebarWidth</key>
<integer>120</integer>
<key>VisibleRegion</key>
<string>{{0, 0}, {559, 735}}</string>
<key>Zoom</key>
<real>1</real>
<key>ZoomValues</key>
<array>
<array>
<string>Canevas 1</string>
<real>1</real>
<real>1</real>
</array>
</array>
</dict>
</dict>
</plist>

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -16,18 +16,128 @@ 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 :doc:`built-in
middleware reference </ref/middleware>`.
.. versionchanged:: 1.10
A new style of middleware was introduced for use with the new
:setting:`MIDDLEWARE` setting. If you're using the old
:setting:`MIDDLEWARE_CLASSES` setting, you'll need to :ref:`adapt old,
custom middleware <upgrading-middleware>` before using the new setting.
This document describes new-style middleware. Refer to this page in older
versions of the documentation for a description of how old-style middleware
works.
Writing your own middleware
===========================
A middleware factory is a callable that takes a ``get_response`` callable and
returns a middleware. A middleware is a callable that takes a request and
returns a response, just like a view.
A middleware can be written as a function that looks like this::
def simple_middleware(get_response):
# One-time configuration and initialization.
def middleware(request):
# Code to be executed for each request before
# the view is called.
try:
response = get_response(request)
except Exception as e:
# Code to handle an exception that wasn't caught
# further up the chain, if desired.
...
# Code to be executed for each request/response after
# the view is called.
return response
return middleware
Or it can be written as a class with a ``__call__()`` method, like this::
class SimpleMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
# One-time configuration and initialization.
def __call__(self, request):
# Code to be executed for each request before
# the view is called.
try:
response = self.get_response(request)
except Exception as e:
# Code to handle an exception that wasn't caught
# further up the chain, if desired.
...
# Code to be executed for each request/response after
# the view is called.
return response
In both examples, the ``try``/``except`` isn't required if the middleware
doesn't need to handle any exceptions. If it is included, it should probably
catch something more specific than ``Exception``.
The ``get_response`` callable provided by Django might be the actual view (if
this is the last listed middleware) or it might be the next middleware in the
chain. The current middleware doesn't need to know or care what exactly it is,
just that it represents whatever comes next.
The above is a slight simplification -- the ``get_response`` callable for the
last middleware in the chain won't be the actual view but rather a wrapper
method from the handler which takes care of applying :ref:`view middleware
<view-middleware>`, calling the view with appropriate URL arguments, and
applying :ref:`template-response <template-response-middleware>` middleware.
Middleware can live anywhere on your Python path.
``__init__(get_response)``
--------------------------
Middleware classes must accept a ``get_response`` argument. You can also
initialize some global state for the middleware. Keep in mind a couple of
caveats:
* Django initializes your middleware with only the ``get_response`` argument,
so you can't define ``__init__()`` as requiring any other arguments.
* Unlike the ``__call__()`` method which get called once per request,
``__init__()`` is called only *once*, when the Web server starts.
.. versionchanged:: 1.10
In older versions, ``__init__`` was not called until the Web server
responded to its first request.
If you want to allow your middleware to be used in Django 1.9 and earlier,
make ``get_response`` an optional argument (``get_response=None``).
Marking middleware as unused
----------------------------
It's sometimes useful to determine at startup time whether a piece of
middleware should be used. In these cases, your middleware's ``__init__()``
method may raise :exc:`~django.core.exceptions.MiddlewareNotUsed`. Django will
then remove that middleware from the middleware process and log a debug message
to the :ref:`django-request-logger` logger when :setting:`DEBUG` is ``True``.
Activating middleware
=====================
To activate a middleware component, add it to the
:setting:`MIDDLEWARE_CLASSES` list in your Django settings.
To activate a middleware component, add it to the :setting:`MIDDLEWARE` 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,
In :setting:`MIDDLEWARE`, each middleware component is represented by a string:
the full Python path to the middleware's class or function name. For example,
here's the default value created by :djadmin:`django-admin startproject
<startproject>`::
MIDDLEWARE_CLASSES = [
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
@@ -37,13 +147,12 @@ here's the default value created by :djadmin:`django-admin startproject
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
A Django installation doesn't require any middleware —
:setting:`MIDDLEWARE_CLASSES` can be empty, if you'd like — but it's strongly
suggested that you at least use
A Django installation doesn't require any middleware — :setting:`MIDDLEWARE`
can be empty, if you'd like — but it's strongly suggested that you at least use
:class:`~django.middleware.common.CommonMiddleware`.
The order in :setting:`MIDDLEWARE_CLASSES` matters because a middleware can
depend on other middleware. For instance,
The order in :setting:`MIDDLEWARE` matters because a middleware can depend on
other middleware. For instance,
:class:`~django.contrib.auth.middleware.AuthenticationMiddleware` stores the
authenticated user in the session; therefore, it must run after
:class:`~django.contrib.sessions.middleware.SessionMiddleware`. See
@@ -54,55 +163,21 @@ Hooks and application order
===========================
During the request phase, before calling the view, Django applies middleware
in the order it's defined in :setting:`MIDDLEWARE_CLASSES`, top-down. Two
hooks are available:
in the order it's defined in :setting:`MIDDLEWARE`, top-down. You can think of
it like an onion: each middleware class is a "layer" that wraps the view.
* :meth:`process_request`
* :meth:`process_view`
Middleware see only the changes made by middleware that run before it. A
middleware (and the view) is skipped entirely if a preceding middleware
short-circuits by returning a response without ever calling ``get_response``.
That response will only pass through the middleware that have already run.
During the response phase, after calling the view, middleware are applied in
reverse order, from the bottom up. Three hooks are available:
Similarly, a middleware that sees the request on the way in and doesn't return
a response is guaranteed that it will always see the response on the way back
out. If the middleware also wants to see any uncaught exception on the way out,
it can wrap its call to ``get_response()`` in a ``try``/``except``.
* :meth:`process_exception` (only if the view raised an exception)
* :meth:`process_template_response` (only for template responses)
* :meth:`process_response`
.. image:: _images/middleware.*
:alt: middleware application order
:width: 481
:height: 409
If you prefer, you can also think of it like an onion: each middleware class
is a "layer" that wraps the view.
The behavior of each hook is described below.
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(request)
``request`` is an :class:`~django.http.HttpRequest` object.
``process_request()`` is called on each request, before Django decides which
view to execute.
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_request()`` middleware, then, ``process_view()``
middleware, and finally, 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
apply response middleware to that :class:`~django.http.HttpResponse`, and
return the result.
Besides the middleware pattern described earlier, you can add two other methods
to class-based middleware:
.. _view-middleware:
@@ -125,14 +200,13 @@ 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 view or exception middleware, or the appropriate
view; it'll apply response middleware to that
:class:`~django.http.HttpResponse`, and return the result.
bother calling the appropriate view; it'll apply response middleware to that
:class:`~django.http.HttpResponse` and return the result.
.. note::
Accessing :attr:`request.POST <django.http.HttpRequest.POST>` inside
middleware from ``process_request`` or ``process_view`` will prevent any
middleware before the view runs or in ``process_view()`` will prevent any
view running after the middleware from being able to :ref:`modify the
upload handlers for the request <modifying_upload_handlers_on_the_fly>`,
and should normally be avoided.
@@ -170,41 +244,8 @@ called.
Middleware are run in reverse order during the response phase, which
includes ``process_template_response()``.
.. _response-middleware:
``process_response()``
----------------------
.. method:: process_response(request, response)
``request`` is an :class:`~django.http.HttpRequest` object. ``response`` is
the :class:`~django.http.HttpResponse` or
:class:`~django.http.StreamingHttpResponse` object returned by a Django view
or by a middleware.
``process_response()`` is called on all responses before they're returned to
the browser.
It must return an :class:`~django.http.HttpResponse` or
:class:`~django.http.StreamingHttpResponse` object. It could alter the given
``response``, or it could create and return a brand-new
:class:`~django.http.HttpResponse` or
:class:`~django.http.StreamingHttpResponse`.
Unlike the ``process_request()`` and ``process_view()`` methods, the
``process_response()`` method is always called, even if the
``process_request()`` and ``process_view()`` methods of the same middleware
class were skipped (because an earlier middleware method returned an
:class:`~django.http.HttpResponse`). In particular, this means that your
``process_response()`` method cannot rely on setup done in
``process_request()``.
Finally, remember that during the response phase, middleware are applied in
reverse order, from the bottom up. This means classes defined at the end of
:setting:`MIDDLEWARE_CLASSES` will be run first.
Dealing with streaming responses
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
================================
Unlike :class:`~django.http.HttpResponse`,
:class:`~django.http.StreamingHttpResponse` does not have a ``content``
@@ -229,66 +270,62 @@ must test for streaming responses and adjust their behavior accordingly::
.. _exception-middleware:
``process_exception()``
-----------------------
Exception middleware
====================
.. method:: process_exception(request, exception)
A middleware that does some custom exception handling might looks like this::
``request`` is an :class:`~django.http.HttpRequest` object. ``exception`` is an
``Exception`` object raised by the view function.
class ExceptionMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
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 template response and response
middleware will be applied, and the resulting response returned to the
browser. Otherwise, default exception handling kicks in.
def __call__(self, request):
try:
response = self.get_response(request)
except Exception as e:
# Do something with the exception and possibly reraise it
# unless you wish to silence it.
...
return response
Again, middleware are run in reverse order during the response phase, which
includes ``process_exception``. If an exception middleware returns a response,
the middleware classes above that middleware will not be called at all.
Middleware that wants to do something for all exception responses, an HTTP 404
for example, need to both catch the appropriate exception (e.g. ``Http404``)
and look for regular responses with the status code of interest. You can
subclass :class:`~django.middleware.exception.ExceptionMiddleware` if you want
to transform exceptions into the appropriate response.
``__init__()``
--------------
.. _upgrading-middleware:
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:
Upgrading pre-Django 1.10-style middleware
==========================================
* Django initializes your middleware without any arguments, so you can't
define ``__init__`` as requiring any arguments.
.. class:: django.utils.deprecation.MiddlewareMixin
:module:
* Unlike the ``process_*`` methods which get called once per request,
``__init__`` gets called only *once*, when the Web server starts.
Django provides ``django.utils.deprecation.MiddlewareMixin`` to ease providing
the existing built-in middleware in both new-style and old-style forms and to
ease similar conversions of third-party middleware.
.. versionchanged:: 1.10
In most cases, this mixin will be sufficient to convert a middleware with
sufficient backwards-compatibility; the new short-circuiting semantics will be
harmless or even beneficial to the existing middleware.
In older versions, ``__init__`` was not called until the Web server
responded to its first request.
In a few cases, a middleware class may need more invasive changes to adjust to
the new semantics.
Marking middleware as unused
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For example, in the current request-handling logic, the handler transforms any
exception that passes through all ``process_exception`` middleware uncaught
into a response with appropriate status code (e.g. 404, 403, 400, or 500), and
then passes that response through the full chain of ``process_response``
middleware.
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 :exc:`django.core.exceptions.MiddlewareNotUsed`. Django will then remove
that piece of middleware from the middleware process and a debug message will
be logged to the ``django.request`` logger when :setting:`DEBUG` is set to
``True``.
In new-style middleware, a given middleware only gets one shot at a given
response or uncaught exception "on the way out," and will see either a returned
response or an uncaught exception, but not both.
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 :doc:`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! :doc:`Let us know
</internals/contributing/index>`, and we'll consider adding it to Django.
This means that certain middleware which want to do something with all 404
responses (for example, the ``RedirectFallbackMiddleware`` and
``FlatpageFallbackMiddleware`` in ``django.contrib.redirects`` and
``django.contrib.flatpages``) now need to watch out for both a 404 response
and an uncaught ``Http404`` exception. They do this by subclassing
:class:`~django.middleware.exception.ExceptionMiddleware`.

View File

@@ -18,13 +18,13 @@ Sessions are implemented via a piece of :doc:`middleware </ref/middleware>`.
To enable session functionality, do the following:
* Edit the :setting:`MIDDLEWARE_CLASSES` setting and make sure
it contains ``'django.contrib.sessions.middleware.SessionMiddleware'``.
The default ``settings.py`` created by ``django-admin startproject``
has ``SessionMiddleware`` activated.
* Edit the :setting:`MIDDLEWARE` setting and make sure it contains
``'django.contrib.sessions.middleware.SessionMiddleware'``. The default
``settings.py`` created by ``django-admin startproject`` has
``SessionMiddleware`` activated.
If you don't want to use sessions, you might as well remove the
``SessionMiddleware`` line from :setting:`MIDDLEWARE_CLASSES` and
``SessionMiddleware`` line from :setting:`MIDDLEWARE` and
``'django.contrib.sessions'`` from your :setting:`INSTALLED_APPS`.
It'll save you a small bit of overhead.

View File

@@ -41,8 +41,8 @@ algorithm the system follows to determine which Python code to execute:
1. Django determines the root URLconf module to use. Ordinarily,
this is the value of the :setting:`ROOT_URLCONF` setting, but if the incoming
``HttpRequest`` object has a :attr:`~django.http.HttpRequest.urlconf`
attribute (set by middleware :ref:`request processing <request-middleware>`),
its value will be used in place of the :setting:`ROOT_URLCONF` setting.
attribute (set by middleware), its value will be used in place of the
:setting:`ROOT_URLCONF` setting.
2. Django loads that Python module and looks for the variable
``urlpatterns``. This should be a Python list of :func:`django.conf.urls.url`