| 1 | | =================== |
| 2 | | How to use sessions |
| 3 | | =================== |
| 4 | | |
| 5 | | Django provides full support for anonymous sessions. The session framework lets |
| 6 | | you store and retrieve arbitrary data on a per-site-visitor basis. It stores |
| 7 | | data on the server side and abstracts the sending and receiving of cookies. |
| 8 | | Cookies contain a session ID -- not the data itself. |
| 9 | | |
| 10 | | Enabling sessions |
| 11 | | ================= |
| 12 | | |
| 13 | | Sessions are implemented via a piece of middleware_ and a Django model. |
| 14 | | |
| 15 | | To enable session functionality, do these two things: |
| 16 | | |
| 17 | | * Edit the ``MIDDLEWARE_CLASSES`` setting and make sure |
| 18 | | ``MIDDLEWARE_CLASSES`` contains ``'django.contrib.sessions.middleware.SessionMiddleware'``. |
| 19 | | The default ``settings.py`` created by ``django-admin.py startproject`` has |
| 20 | | ``SessionMiddleware`` activated. |
| 21 | | |
| 22 | | * Add ``'django.contrib.sessions'`` to your ``INSTALLED_APPS`` setting, and |
| 23 | | run ``manage.py syncdb`` to install the single database table that stores |
| 24 | | session data. |
| 25 | | |
| 26 | | If you don't want to use sessions, you might as well remove the |
| 27 | | ``SessionMiddleware`` line from ``MIDDLEWARE_CLASSES`` and ``'django.contrib.sessions'`` |
| 28 | | from your ``INSTALLED_APPS``. It'll save you a small bit of overhead. |
| 29 | | |
| 30 | | .. _middleware: ../middleware/ |
| 31 | | |
| 32 | | Using sessions in views |
| 33 | | ======================= |
| 34 | | |
| 35 | | When ``SessionMiddleware`` is activated, each ``HttpRequest`` object -- the |
| 36 | | first argument to any Django view function -- will have a ``session`` |
| 37 | | attribute, which is a dictionary-like object. You can read it and write to it. |
| 38 | | |
| 39 | | It implements the following standard dictionary methods: |
| 40 | | |
| 41 | | * ``__getitem__(key)`` |
| 42 | | Example: ``fav_color = request.session['fav_color']`` |
| 43 | | |
| 44 | | * ``__setitem__(key, value)`` |
| 45 | | Example: ``request.session['fav_color'] = 'blue'`` |
| 46 | | |
| 47 | | * ``__delitem__(key)`` |
| 48 | | Example: ``del request.session['fav_color']``. This raises ``KeyError`` |
| 49 | | if the given ``key`` isn't already in the session. |
| 50 | | |
| 51 | | * ``__contains__(key)`` |
| 52 | | Example: ``'fav_color' in request.session`` |
| 53 | | |
| 54 | | * ``get(key, default=None)`` |
| 55 | | Example: ``fav_color = request.session.get('fav_color', 'red')`` |
| 56 | | |
| 57 | | * ``keys()`` |
| 58 | | |
| 59 | | * ``items()`` |
| 60 | | |
| 61 | | It also has these three methods: |
| 62 | | |
| 63 | | * ``set_test_cookie()`` |
| 64 | | Sets a test cookie to determine whether the user's browser supports |
| 65 | | cookies. Due to the way cookies work, you won't be able to test this |
| 66 | | until the user's next page request. See "Setting test cookies" below for |
| 67 | | more information. |
| 68 | | |
| 69 | | * ``test_cookie_worked()`` |
| 70 | | Returns either ``True`` or ``False``, depending on whether the user's |
| 71 | | browser accepted the test cookie. Due to the way cookies work, you'll |
| 72 | | have to call ``set_test_cookie()`` on a previous, separate page request. |
| 73 | | See "Setting test cookies" below for more information. |
| 74 | | |
| 75 | | * ``delete_test_cookie()`` |
| 76 | | Deletes the test cookie. Use this to clean up after yourself. |
| 77 | | |
| 78 | | You can edit ``request.session`` at any point in your view. You can edit it |
| 79 | | multiple times. |
| 80 | | |
| 81 | | Session object guidelines |
| 82 | | ------------------------- |
| 83 | | |
| 84 | | * Use normal Python strings as dictionary keys on ``request.session``. This |
| 85 | | is more of a convention than a hard-and-fast rule. |
| 86 | | |
| 87 | | * Session dictionary keys that begin with an underscore are reserved for |
| 88 | | internal use by Django. |
| 89 | | |
| 90 | | * Don't override ``request.session`` with a new object, and don't access or |
| 91 | | set its attributes. Use it like a Python dictionary. |
| 92 | | |
| 93 | | Examples |
| 94 | | -------- |
| 95 | | |
| 96 | | This simplistic view sets a ``has_commented`` variable to ``True`` after a user |
| 97 | | posts a comment. It doesn't let a user post a comment more than once:: |
| 98 | | |
| 99 | | def post_comment(request, new_comment): |
| 100 | | if request.session.get('has_commented', False): |
| 101 | | return HttpResponse("You've already commented.") |
| 102 | | c = comments.Comment(comment=new_comment) |
| 103 | | c.save() |
| 104 | | request.session['has_commented'] = True |
| 105 | | return HttpResponse('Thanks for your comment!') |
| 106 | | |
| 107 | | This simplistic view logs in a "member" of the site:: |
| 108 | | |
| 109 | | def login(request): |
| 110 | | m = Member.objects.get(username=request.POST['username']) |
| 111 | | if m.password == request.POST['password']: |
| 112 | | request.session['member_id'] = m.id |
| 113 | | return HttpResponse("You're logged in.") |
| 114 | | else: |
| 115 | | return HttpResponse("Your username and password didn't match.") |
| 116 | | |
| 117 | | ...And this one logs a member out, according to ``login()`` above:: |
| 118 | | |
| 119 | | def logout(request): |
| 120 | | try: |
| 121 | | del request.session['member_id'] |
| 122 | | except KeyError: |
| 123 | | pass |
| 124 | | return HttpResponse("You're logged out.") |
| 125 | | |
| 126 | | Setting test cookies |
| 127 | | ==================== |
| 128 | | |
| 129 | | As a convenience, Django provides an easy way to test whether the user's |
| 130 | | browser accepts cookies. Just call ``request.session.set_test_cookie()`` in a |
| 131 | | view, and call ``request.session.test_cookie_worked()`` in a subsequent view -- |
| 132 | | not in the same view call. |
| 133 | | |
| 134 | | This awkward split between ``set_test_cookie()`` and ``test_cookie_worked()`` |
| 135 | | is necessary due to the way cookies work. When you set a cookie, you can't |
| 136 | | actually tell whether a browser accepted it until the browser's next request. |
| 137 | | |
| 138 | | It's good practice to use ``delete_test_cookie()`` to clean up after yourself. |
| 139 | | Do this after you've verified that the test cookie worked. |
| 140 | | |
| 141 | | Here's a typical usage example:: |
| 142 | | |
| 143 | | def login(request): |
| 144 | | if request.method == 'POST': |
| 145 | | if request.session.test_cookie_worked(): |
| 146 | | request.session.delete_test_cookie() |
| 147 | | return HttpResponse("You're logged in.") |
| 148 | | else: |
| 149 | | return HttpResponse("Please enable cookies and try again.") |
| 150 | | request.session.set_test_cookie() |
| 151 | | return render_to_response('foo/login_form.html') |
| 152 | | |
| 153 | | Using sessions out of views |
| 154 | | =========================== |
| 155 | | |
| 156 | | Internally, each session is just a normal Django model. The ``Session`` model |
| 157 | | is defined in ``django/contrib/sessions/models.py``. Because it's a normal |
| 158 | | model, you can access sessions using the normal Django database API:: |
| 159 | | |
| 160 | | >>> from django.contrib.sessions.models import Session |
| 161 | | >>> s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead') |
| 162 | | >>> s.expire_date |
| 163 | | datetime.datetime(2005, 8, 20, 13, 35, 12) |
| 164 | | |
| 165 | | Note that you'll need to call ``get_decoded()`` to get the session dictionary. |
| 166 | | This is necessary because the dictionary is stored in an encoded format:: |
| 167 | | |
| 168 | | >>> s.session_data |
| 169 | | 'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...' |
| 170 | | >>> s.get_decoded() |
| 171 | | {'user_id': 42} |
| 172 | | |
| 173 | | When sessions are saved |
| 174 | | ======================= |
| 175 | | |
| 176 | | By default, Django only saves to the session database when the session has been |
| 177 | | modified -- that is if any of its dictionary values have been assigned or |
| 178 | | deleted:: |
| 179 | | |
| 180 | | # Session is modified. |
| 181 | | request.session['foo'] = 'bar' |
| 182 | | |
| 183 | | # Session is modified. |
| 184 | | del request.session['foo'] |
| 185 | | |
| 186 | | # Session is modified. |
| 187 | | request.session['foo'] = {} |
| 188 | | |
| 189 | | # Gotcha: Session is NOT modified, because this alters |
| 190 | | # request.session['foo'] instead of request.session. |
| 191 | | request.session['foo']['bar'] = 'baz' |
| 192 | | |
| 193 | | To change this default behavior, set the ``SESSION_SAVE_EVERY_REQUEST`` setting |
| 194 | | to ``True``. If ``SESSION_SAVE_EVERY_REQUEST`` is ``True``, Django will save |
| 195 | | the session to the database on every single request. |
| 196 | | |
| 197 | | Note that the session cookie is only sent when a session has been created or |
| 198 | | modified. If ``SESSION_SAVE_EVERY_REQUEST`` is ``True``, the session cookie |
| 199 | | will be sent on every request. |
| 200 | | |
| 201 | | Similarly, the ``expires`` part of a session cookie is updated each time the |
| 202 | | session cookie is sent. |
| 203 | | |
| 204 | | Browser-length sessions vs. persistent sessions |
| 205 | | =============================================== |
| 206 | | |
| 207 | | You can control whether the session framework uses browser-length sessions vs. |
| 208 | | persistent sessions with the ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` setting. |
| 209 | | |
| 210 | | By default, ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` is set to ``False``, which |
| 211 | | means session cookies will be stored in users' browsers for as long as |
| 212 | | ``SESSION_COOKIE_AGE``. Use this if you don't want people to have to log in |
| 213 | | every time they open a browser. |
| 214 | | |
| 215 | | If ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` is set to ``True``, Django will use |
| 216 | | browser-length cookies -- cookies that expire as soon as the user closes his or |
| 217 | | her browser. Use this if you want people to have to log in every time they open |
| 218 | | a browser. |
| 219 | | |
| 220 | | Clearing the session table |
| 221 | | ========================== |
| 222 | | |
| 223 | | Note that session data can accumulate in the ``django_session`` database table |
| 224 | | and Django does *not* provide automatic purging. Therefore, it's your job to |
| 225 | | purge expired sessions on a regular basis. |
| 226 | | |
| 227 | | To understand this problem, consider what happens when a user uses a session. |
| 228 | | When a user logs in, Django adds a row to the ``django_session`` database |
| 229 | | table. Django updates this row each time the session data changes. If the user |
| 230 | | logs out manually, Django deletes the row. But if the user does *not* log out, |
| 231 | | the row never gets deleted. |
| 232 | | |
| 233 | | Django provides a sample clean-up script in ``django/bin/daily_cleanup.py``. |
| 234 | | That script deletes any session in the session table whose ``expire_date`` is |
| 235 | | in the past -- but your application may have different requirements. |
| 236 | | |
| 237 | | Settings |
| 238 | | ======== |
| 239 | | |
| 240 | | A few `Django settings`_ give you control over session behavior: |
| 241 | | |
| 242 | | SESSION_COOKIE_AGE |
| 243 | | ------------------ |
| 244 | | |
| 245 | | Default: ``1209600`` (2 weeks, in seconds) |
| 246 | | |
| 247 | | The age of session cookies, in seconds. |
| 248 | | |
| 249 | | SESSION_COOKIE_DOMAIN |
| 250 | | --------------------- |
| 251 | | |
| 252 | | Default: ``None`` |
| 253 | | |
| 254 | | The domain to use for session cookies. Set this to a string such as |
| 255 | | ``".lawrence.com"`` for cross-domain cookies, or use ``None`` for a standard |
| 256 | | domain cookie. |
| 257 | | |
| 258 | | SESSION_COOKIE_NAME |
| 259 | | ------------------- |
| 260 | | |
| 261 | | Default: ``'sessionid'`` |
| 262 | | |
| 263 | | The name of the cookie to use for sessions. This can be whatever you want. |
| 264 | | |
| 265 | | SESSION_COOKIE_SECURE |
| 266 | | --------------------- |
| 267 | | |
| 268 | | Default: ``False`` |
| 269 | | |
| 270 | | Whether to use a secure cookie for the session cookie. If this is set to |
| 271 | | ``True``, the cookie will be marked as "secure," which means browsers may |
| 272 | | ensure that the cookie is only sent under an HTTPS connection. |
| 273 | | |
| 274 | | SESSION_EXPIRE_AT_BROWSER_CLOSE |
| 275 | | ------------------------------- |
| 276 | | |
| 277 | | Default: ``False`` |
| 278 | | |
| 279 | | Whether to expire the session when the user closes his or her browser. See |
| 280 | | "Browser-length sessions vs. persistent sessions" above. |
| 281 | | |
| 282 | | SESSION_SAVE_EVERY_REQUEST |
| 283 | | -------------------------- |
| 284 | | |
| 285 | | Default: ``False`` |
| 286 | | |
| 287 | | Whether to save the session data on every request. If this is ``False`` |
| 288 | | (default), then the session data will only be saved if it has been modified -- |
| 289 | | that is, if any of its dictionary values have been assigned or deleted. |
| 290 | | |
| 291 | | .. _Django settings: ../settings/ |
| 292 | | |
| 293 | | Technical details |
| 294 | | ================= |
| 295 | | |
| 296 | | * The session dictionary should accept any pickleable Python object. See |
| 297 | | `the pickle module`_ for more information. |
| 298 | | |
| 299 | | * Session data is stored in a database table named ``django_session`` . |
| 300 | | |
| 301 | | * Django only sends a cookie if it needs to. If you don't set any session |
| 302 | | data, it won't send a session cookie. |
| 303 | | |
| 304 | | .. _`the pickle module`: http://www.python.org/doc/current/lib/module-pickle.html |
| 305 | | |
| 306 | | Session IDs in URLs |
| 307 | | =================== |
| 308 | | |
| 309 | | The Django sessions framework is entirely, and solely, cookie-based. It does |
| 310 | | not fall back to putting session IDs in URLs as a last resort, as PHP does. |
| 311 | | This is an intentional design decision. Not only does that behavior make URLs |
| 312 | | ugly, it makes your site vulnerable to session-ID theft via the "Referer" |
| 313 | | header. |
| | 1 | =================== |
| | 2 | How to use sessions |
| | 3 | =================== |
| | 4 | |
| | 5 | Django provides full support for anonymous sessions. The session framework lets |
| | 6 | you store and retrieve arbitrary data on a per-site-visitor basis. It stores |
| | 7 | data on the server side and abstracts the sending and receiving of cookies. |
| | 8 | Cookies contain a session ID -- not the data itself. |
| | 9 | |
| | 10 | Enabling sessions |
| | 11 | ================= |
| | 12 | |
| | 13 | Sessions are implemented via a piece of middleware_ and a Django model. |
| | 14 | |
| | 15 | To enable session functionality, do these two things: |
| | 16 | |
| | 17 | * Edit the ``MIDDLEWARE_CLASSES`` setting and make sure |
| | 18 | ``MIDDLEWARE_CLASSES`` contains ``'django.contrib.sessions.middleware.SessionMiddleware'``. |
| | 19 | The default ``settings.py`` created by ``django-admin.py startproject`` has |
| | 20 | ``SessionMiddleware`` activated. |
| | 21 | |
| | 22 | * Add ``'django.contrib.sessions'`` to your ``INSTALLED_APPS`` setting, and |
| | 23 | run ``manage.py syncdb`` to install the single database table that stores |
| | 24 | session data. |
| | 25 | |
| | 26 | If you don't want to use sessions, you might as well remove the |
| | 27 | ``SessionMiddleware`` line from ``MIDDLEWARE_CLASSES`` and ``'django.contrib.sessions'`` |
| | 28 | from your ``INSTALLED_APPS``. It'll save you a small bit of overhead. |
| | 29 | |
| | 30 | .. _middleware: ../middleware/ |
| | 31 | |
| | 32 | Using sessions in views |
| | 33 | ======================= |
| | 34 | |
| | 35 | When ``SessionMiddleware`` is activated, each ``HttpRequest`` object -- the |
| | 36 | first argument to any Django view function -- will have a ``session`` |
| | 37 | attribute, which is a dictionary-like object. You can read it and write to it. |
| | 38 | |
| | 39 | It implements the following standard dictionary methods: |
| | 40 | |
| | 41 | * ``__getitem__(key)`` |
| | 42 | Example: ``fav_color = request.session['fav_color']`` |
| | 43 | |
| | 44 | * ``__setitem__(key, value)`` |
| | 45 | Example: ``request.session['fav_color'] = 'blue'`` |
| | 46 | |
| | 47 | * ``__delitem__(key)`` |
| | 48 | Example: ``del request.session['fav_color']``. This raises ``KeyError`` |
| | 49 | if the given ``key`` isn't already in the session. |
| | 50 | |
| | 51 | * ``__contains__(key)`` |
| | 52 | Example: ``'fav_color' in request.session`` |
| | 53 | |
| | 54 | * ``get(key, default=None)`` |
| | 55 | Example: ``fav_color = request.session.get('fav_color', 'red')`` |
| | 56 | |
| | 57 | * ``keys()`` |
| | 58 | |
| | 59 | * ``items()`` |
| | 60 | |
| | 61 | It also has these four methods: |
| | 62 | |
| | 63 | * ``set_test_cookie()`` |
| | 64 | Sets a test cookie to determine whether the user's browser supports |
| | 65 | cookies. Due to the way cookies work, you won't be able to test this |
| | 66 | until the user's next page request. See "Setting test cookies" below for |
| | 67 | more information. |
| | 68 | |
| | 69 | * ``test_cookie_worked()`` |
| | 70 | Returns either ``True`` or ``False``, depending on whether the user's |
| | 71 | browser accepted the test cookie. Due to the way cookies work, you'll |
| | 72 | have to call ``set_test_cookie()`` on a previous, separate page request. |
| | 73 | See "Setting test cookies" below for more information. |
| | 74 | |
| | 75 | * ``delete_test_cookie()`` |
| | 76 | Deletes the test cookie. Use this to clean up after yourself. |
| | 77 | |
| | 78 | * ``set_life(val)`` |
| | 79 | It takes an integer, number of seconds for which the session should be |
| | 80 | valid. It can also take django.contrib.session.models.TILL_BROWSER_CLOSE, |
| | 81 | that will quell the session at the close of browser. Calling set_life |
| | 82 | will overwrite the global/default session expiry policy. See |
| | 83 | `browser-length sessions vs. persistent sessions` for default session expiry |
| | 84 | policy. |
| | 85 | |
| | 86 | You can edit ``request.session`` at any point in your view. You can edit it |
| | 87 | multiple times. |
| | 88 | |
| | 89 | Session object guidelines |
| | 90 | ------------------------- |
| | 91 | |
| | 92 | * Use normal Python strings as dictionary keys on ``request.session``. This |
| | 93 | is more of a convention than a hard-and-fast rule. |
| | 94 | |
| | 95 | * Session dictionary keys that begin with an underscore are reserved for |
| | 96 | internal use by Django. |
| | 97 | |
| | 98 | * Don't override ``request.session`` with a new object, and don't access or |
| | 99 | set its attributes. Use it like a Python dictionary. |
| | 100 | |
| | 101 | Examples |
| | 102 | -------- |
| | 103 | |
| | 104 | This simplistic view sets a ``has_commented`` variable to ``True`` after a user |
| | 105 | posts a comment. It doesn't let a user post a comment more than once:: |
| | 106 | |
| | 107 | def post_comment(request, new_comment): |
| | 108 | if request.session.get('has_commented', False): |
| | 109 | return HttpResponse("You've already commented.") |
| | 110 | c = comments.Comment(comment=new_comment) |
| | 111 | c.save() |
| | 112 | request.session['has_commented'] = True |
| | 113 | return HttpResponse('Thanks for your comment!') |
| | 114 | |
| | 115 | This simplistic view logs in a "member" of the site:: |
| | 116 | |
| | 117 | def login(request): |
| | 118 | m = Member.objects.get(username=request.POST['username']) |
| | 119 | if m.password == request.POST['password']: |
| | 120 | request.session['member_id'] = m.id |
| | 121 | return HttpResponse("You're logged in.") |
| | 122 | else: |
| | 123 | return HttpResponse("Your username and password didn't match.") |
| | 124 | |
| | 125 | ...And this one logs a member out, according to ``login()`` above:: |
| | 126 | |
| | 127 | def logout(request): |
| | 128 | try: |
| | 129 | del request.session['member_id'] |
| | 130 | except KeyError: |
| | 131 | pass |
| | 132 | return HttpResponse("You're logged out.") |
| | 133 | |
| | 134 | Setting test cookies |
| | 135 | ==================== |
| | 136 | |
| | 137 | As a convenience, Django provides an easy way to test whether the user's |
| | 138 | browser accepts cookies. Just call ``request.session.set_test_cookie()`` in a |
| | 139 | view, and call ``request.session.test_cookie_worked()`` in a subsequent view -- |
| | 140 | not in the same view call. |
| | 141 | |
| | 142 | This awkward split between ``set_test_cookie()`` and ``test_cookie_worked()`` |
| | 143 | is necessary due to the way cookies work. When you set a cookie, you can't |
| | 144 | actually tell whether a browser accepted it until the browser's next request. |
| | 145 | |
| | 146 | It's good practice to use ``delete_test_cookie()`` to clean up after yourself. |
| | 147 | Do this after you've verified that the test cookie worked. |
| | 148 | |
| | 149 | Here's a typical usage example:: |
| | 150 | |
| | 151 | def login(request): |
| | 152 | if request.method == 'POST': |
| | 153 | if request.session.test_cookie_worked(): |
| | 154 | request.session.delete_test_cookie() |
| | 155 | return HttpResponse("You're logged in.") |
| | 156 | else: |
| | 157 | return HttpResponse("Please enable cookies and try again.") |
| | 158 | request.session.set_test_cookie() |
| | 159 | return render_to_response('foo/login_form.html') |
| | 160 | |
| | 161 | Using sessions out of views |
| | 162 | =========================== |
| | 163 | |
| | 164 | Internally, each session is just a normal Django model. The ``Session`` model |
| | 165 | is defined in ``django/contrib/sessions/models.py``. Because it's a normal |
| | 166 | model, you can access sessions using the normal Django database API:: |
| | 167 | |
| | 168 | >>> from django.contrib.sessions.models import Session |
| | 169 | >>> s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead') |
| | 170 | >>> s.expire_date |
| | 171 | datetime.datetime(2005, 8, 20, 13, 35, 12) |
| | 172 | |
| | 173 | Note that you'll need to call ``get_decoded()`` to get the session dictionary. |
| | 174 | This is necessary because the dictionary is stored in an encoded format:: |
| | 175 | |
| | 176 | >>> s.session_data |
| | 177 | 'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...' |
| | 178 | >>> s.get_decoded() |
| | 179 | {'user_id': 42} |
| | 180 | |
| | 181 | When sessions are saved |
| | 182 | ======================= |
| | 183 | |
| | 184 | By default, Django only saves to the session database when the session has been |
| | 185 | modified -- that is if any of its dictionary values have been assigned or |
| | 186 | deleted:: |
| | 187 | |
| | 188 | # Session is modified. |
| | 189 | request.session['foo'] = 'bar' |
| | 190 | |
| | 191 | # Session is modified. |
| | 192 | del request.session['foo'] |
| | 193 | |
| | 194 | # Session is modified. |
| | 195 | request.session['foo'] = {} |
| | 196 | |
| | 197 | # Gotcha: Session is NOT modified, because this alters |
| | 198 | # request.session['foo'] instead of request.session. |
| | 199 | request.session['foo']['bar'] = 'baz' |
| | 200 | |
| | 201 | To change this default behavior, set the ``SESSION_SAVE_EVERY_REQUEST`` setting |
| | 202 | to ``True``. If ``SESSION_SAVE_EVERY_REQUEST`` is ``True``, Django will save |
| | 203 | the session to the database on every single request. |
| | 204 | |
| | 205 | Note that the session cookie is only sent when a session has been created or |
| | 206 | modified. If ``SESSION_SAVE_EVERY_REQUEST`` is ``True``, the session cookie |
| | 207 | will be sent on every request. |
| | 208 | |
| | 209 | Similarly, the ``expires`` part of a session cookie is updated each time the |
| | 210 | session cookie is sent. |
| | 211 | |
| | 212 | Browser-length sessions vs. persistent sessions |
| | 213 | =============================================== |
| | 214 | |
| | 215 | You can control whether the session framework uses browser-length sessions vs. |
| | 216 | persistent sessions with the ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` setting. |
| | 217 | |
| | 218 | By default, ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` is set to ``False``, which |
| | 219 | means session cookies will be stored in users' browsers for as long as |
| | 220 | ``SESSION_COOKIE_AGE``. Use this if you don't want people to have to log in |
| | 221 | every time they open a browser. |
| | 222 | |
| | 223 | If ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` is set to ``True``, Django will use |
| | 224 | browser-length cookies -- cookies that expire as soon as the user closes his or |
| | 225 | her browser. Use this if you want people to have to log in every time they open |
| | 226 | a browser. |
| | 227 | |
| | 228 | These settings are global defaults, and can be overwritten by explicitly calling |
| | 229 | ``request.session.set_life()`` as described above. |
| | 230 | |
| | 231 | Clearing the session table |
| | 232 | ========================== |
| | 233 | |
| | 234 | Note that session data can accumulate in the ``django_session`` database table |
| | 235 | and Django does *not* provide automatic purging. Therefore, it's your job to |
| | 236 | purge expired sessions on a regular basis. |
| | 237 | |
| | 238 | To understand this problem, consider what happens when a user uses a session. |
| | 239 | When a user logs in, Django adds a row to the ``django_session`` database |
| | 240 | table. Django updates this row each time the session data changes. If the user |
| | 241 | logs out manually, Django deletes the row. But if the user does *not* log out, |
| | 242 | the row never gets deleted. |
| | 243 | |
| | 244 | Django provides a sample clean-up script in ``django/bin/daily_cleanup.py``. |
| | 245 | That script deletes any session in the session table whose ``expire_date`` is |
| | 246 | in the past -- but your application may have different requirements. |
| | 247 | |
| | 248 | Settings |
| | 249 | ======== |
| | 250 | |
| | 251 | A few `Django settings`_ give you control over session behavior: |
| | 252 | |
| | 253 | SESSION_COOKIE_AGE |
| | 254 | ------------------ |
| | 255 | |
| | 256 | Default: ``1209600`` (2 weeks, in seconds) |
| | 257 | |
| | 258 | The age of session cookies, in seconds. |
| | 259 | |
| | 260 | SESSION_COOKIE_DOMAIN |
| | 261 | --------------------- |
| | 262 | |
| | 263 | Default: ``None`` |
| | 264 | |
| | 265 | The domain to use for session cookies. Set this to a string such as |
| | 266 | ``".lawrence.com"`` for cross-domain cookies, or use ``None`` for a standard |
| | 267 | domain cookie. |
| | 268 | |
| | 269 | SESSION_COOKIE_NAME |
| | 270 | ------------------- |
| | 271 | |
| | 272 | Default: ``'sessionid'`` |
| | 273 | |
| | 274 | The name of the cookie to use for sessions. This can be whatever you want. |
| | 275 | |
| | 276 | SESSION_COOKIE_SECURE |
| | 277 | --------------------- |
| | 278 | |
| | 279 | Default: ``False`` |
| | 280 | |
| | 281 | Whether to use a secure cookie for the session cookie. If this is set to |
| | 282 | ``True``, the cookie will be marked as "secure," which means browsers may |
| | 283 | ensure that the cookie is only sent under an HTTPS connection. |
| | 284 | |
| | 285 | SESSION_EXPIRE_AT_BROWSER_CLOSE |
| | 286 | ------------------------------- |
| | 287 | |
| | 288 | Default: ``False`` |
| | 289 | |
| | 290 | Whether to expire the session when the user closes his or her browser. See |
| | 291 | "Browser-length sessions vs. persistent sessions" above. |
| | 292 | |
| | 293 | SESSION_SAVE_EVERY_REQUEST |
| | 294 | -------------------------- |
| | 295 | |
| | 296 | Default: ``False`` |
| | 297 | |
| | 298 | Whether to save the session data on every request. If this is ``False`` |
| | 299 | (default), then the session data will only be saved if it has been modified -- |
| | 300 | that is, if any of its dictionary values have been assigned or deleted. |
| | 301 | |
| | 302 | .. _Django settings: ../settings/ |
| | 303 | |
| | 304 | Technical details |
| | 305 | ================= |
| | 306 | |
| | 307 | * The session dictionary should accept any pickleable Python object. See |
| | 308 | `the pickle module`_ for more information. |
| | 309 | |
| | 310 | * Session data is stored in a database table named ``django_session`` . |
| | 311 | |
| | 312 | * Django only sends a cookie if it needs to. If you don't set any session |
| | 313 | data, it won't send a session cookie. |
| | 314 | |
| | 315 | .. _`the pickle module`: http://www.python.org/doc/current/lib/module-pickle.html |
| | 316 | |
| | 317 | Session IDs in URLs |
| | 318 | =================== |
| | 319 | |
| | 320 | The Django sessions framework is entirely, and solely, cookie-based. It does |
| | 321 | not fall back to putting session IDs in URLs as a last resort, as PHP does. |
| | 322 | This is an intentional design decision. Not only does that behavior make URLs |
| | 323 | ugly, it makes your site vulnerable to session-ID theft via the "Referer" |
| | 324 | header. |