Django

Code

root/django/branches/sqlalchemy/docs/sessions.txt

Revision 4455, 11.0 kB (checked in by rmunn, 2 years ago)

Merged revisions 4186 to 4454 from trunk.

Line 
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 = members.get_object(username__exact=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_object(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 **New in Django development version**
269
270 Default: ``False``
271
272 Whether to use a secure cookie for the session cookie. If this is set to
273 ``True``, the cookie will be marked as "secure," which means browsers may
274 ensure that the cookie is only sent under an HTTPS connection.
275
276 SESSION_EXPIRE_AT_BROWSER_CLOSE
277 -------------------------------
278
279 Default: ``False``
280
281 Whether to expire the session when the user closes his or her browser. See
282 "Browser-length sessions vs. persistent sessions" above.
283
284 SESSION_SAVE_EVERY_REQUEST
285 --------------------------
286
287 Default: ``False``
288
289 Whether to save the session data on every request. If this is ``False``
290 (default), then the session data will only be saved if it has been modified --
291 that is, if any of its dictionary values have been assigned or deleted.
292
293 .. _Django settings: ../settings/
294
295 Technical details
296 =================
297
298     * The session dictionary should accept any pickleable Python object. See
299       `the pickle module`_ for more information.
300
301     * Session data is stored in a database table named ``django_session`` .
302
303     * Django only sends a cookie if it needs to. If you don't set any session
304       data, it won't send a session cookie.
305
306 .. _`the pickle module`: http://www.python.org/doc/current/lib/module-pickle.html
307
308 Session IDs in URLs
309 ===================
310
311 The Django sessions framework is entirely, and solely, cookie-based. It does
312 not fall back to putting session IDs in URLs as a last resort, as PHP does.
313 This is an intentional design decision. Not only does that behavior make URLs
314 ugly, it makes your site vulnerable to session-ID theft via the "Referer"
315 header.
Note: See TracBrowser for help on using the browser.