mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	git-svn-id: http://code.djangoproject.com/svn/django/trunk@1585 bcc190cf-cafb-0310-a4f2-bffc1f526a37
		
			
				
	
	
		
			257 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			257 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| ===================
 | |
| How to use sessions
 | |
| ===================
 | |
| 
 | |
| Django provides full support for anonymous sessions. The session framework lets
 | |
| you store and retrieve arbitrary data on a per-site-visitor basis. It stores
 | |
| data on the server side and abstracts the sending and receiving of cookies.
 | |
| Cookies contain a session ID -- not the data itself.
 | |
| 
 | |
| Enabling sessions
 | |
| =================
 | |
| 
 | |
| Session functionality is enabled by default.
 | |
| 
 | |
| You can turn session functionality on and off by editing the
 | |
| ``MIDDLEWARE_CLASSES`` setting. To activate sessions, make sure
 | |
| ``MIDDLEWARE_CLASSES`` contains ``"django.middleware.sessions.SessionMiddleware"``.
 | |
| 
 | |
| If you're dealing with an admin site, make sure the ``SessionMiddleware`` line
 | |
| appears before the ``AdminUserRequired`` line. (The middleware classes are
 | |
| applied in order, and the admin middleware requires that the session middleware
 | |
| come first.)
 | |
| 
 | |
| If you don't want to use sessions, you might as well remove the
 | |
| ``SessionMiddleware`` line from ``MIDDLEWARE_CLASSES``. It'll save you a small
 | |
| bit of overhead.
 | |
| 
 | |
| Using sessions in views
 | |
| =======================
 | |
| 
 | |
| Each ``HttpRequest`` object -- the first argument to any Django view function --
 | |
| has a ``session`` attribute, which is a dictionary-like object. You can read
 | |
| it and write to it.
 | |
| 
 | |
| It implements the following standard dictionary methods:
 | |
| 
 | |
|     * ``__getitem__(key)``
 | |
|       Example: ``fav_color = request.session['fav_color']``
 | |
| 
 | |
|     * ``__setitem__(key, value)``
 | |
|       Example: ``request.session['fav_color'] = 'blue'``
 | |
| 
 | |
|     * ``__delitem__(key)``
 | |
|       Example: ``del request.session['fav_color']``. This raises ``KeyError``
 | |
|       if the given ``key`` isn't already in the session.
 | |
| 
 | |
|     * ``get(key, default=None)``
 | |
|       Example: ``fav_color = request.session.get('fav_color', 'red')``
 | |
| 
 | |
| It also has these three methods:
 | |
| 
 | |
|     * ``set_test_cookie()``
 | |
|       Sets a test cookie to determine whether the user's browser supports
 | |
|       cookies. Due to the way cookies work, you won't be able to test this
 | |
|       until the user's next page request. See "Setting test cookies" below for
 | |
|       more information.
 | |
| 
 | |
|     * ``test_cookie_worked()``
 | |
|       Returns either ``True`` or ``False``, depending on whether the user's
 | |
|       browser accepted the test cookie. Due to the way cookies work, you'll
 | |
|       have to call ``set_test_cookie()`` on a previous, separate page request.
 | |
|       See "Setting test cookies" below for more information.
 | |
| 
 | |
|     * ``delete_test_cookie()``
 | |
|       Deletes the test cookie. Use this to clean up after yourself.
 | |
| 
 | |
| You can edit ``request.session`` at any point in your view. You can edit it
 | |
| multiple times.
 | |
| 
 | |
| Session object guidelines
 | |
| -------------------------
 | |
| 
 | |
|     * Use normal Python strings as dictionary keys on ``request.session``. This
 | |
|       is more of a convention than a hard-and-fast rule.
 | |
| 
 | |
|     * Session dictionary keys that begin with an underscore are reserved for
 | |
|       internal use by Django.
 | |
| 
 | |
|     * Don't override ``request.session`` with a new object, and don't access or
 | |
|       set its attributes. Use it like a Python dictionary.
 | |
| 
 | |
| Examples
 | |
| --------
 | |
| 
 | |
| This simplistic view sets a ``has_commented`` variable to ``True`` after a user
 | |
| posts a comment. It doesn't let a user post a comment more than once::
 | |
| 
 | |
|     def post_comment(request, new_comment):
 | |
|         if request.session.get('has_commented', False):
 | |
|             return HttpResponse("You've already commented.")
 | |
|         c = comments.Comment(comment=new_comment)
 | |
|         c.save()
 | |
|         request.session['has_commented'] = True
 | |
|         return HttpResponse('Thanks for your comment!')
 | |
| 
 | |
| This simplistic view logs in a "member" of the site::
 | |
| 
 | |
|     def login(request):
 | |
|         m = members.get_object(username__exact=request.POST['username'])
 | |
|         if m.password == request.POST['password']:
 | |
|             request.session['member_id'] = m.id
 | |
|             return HttpResponse("You're logged in.")
 | |
|         else:
 | |
|             return HttpResponse("Your username and password didn't match.")
 | |
| 
 | |
| ...And this one logs a member out, according to ``login()`` above::
 | |
| 
 | |
|     def logout(request):
 | |
|         try:
 | |
|             del request.session['member_id']
 | |
|         except KeyError:
 | |
|             pass
 | |
|         return HttpResponse("You're logged out.")
 | |
| 
 | |
| Setting test cookies
 | |
| ====================
 | |
| 
 | |
| As a convenience, Django provides an easy way to test whether the user's
 | |
| browser accepts cookies. Just call ``request.session.set_test_cookie()`` in a
 | |
| view, and call ``request.session.test_cookie_worked()`` in a subsequent view --
 | |
| not in the same view call.
 | |
| 
 | |
| This awkward split between ``set_test_cookie()`` and ``test_cookie_worked()``
 | |
| is necessary due to the way cookies work. When you set a cookie, you can't
 | |
| actually tell whether a browser accepted it until the browser's next request.
 | |
| 
 | |
| It's good practice to use ``delete_test_cookie()`` to clean up after yourself.
 | |
| Do this after you've verified that the test cookie worked.
 | |
| 
 | |
| Here's a typical usage example::
 | |
| 
 | |
|     def login(request):
 | |
|         if request.POST:
 | |
|             if request.session.test_cookie_worked():
 | |
|                 request.session.delete_test_cookie()
 | |
|                 return HttpResponse("You're logged in.")
 | |
|             else:
 | |
|                 return HttpResponse("Please enable cookies and try again.")
 | |
|         request.session.set_test_cookie()
 | |
|         return render_to_response('foo/login_form')
 | |
| 
 | |
| Using sessions out of views
 | |
| ===========================
 | |
| 
 | |
| Internally, each session is just a normal Django model. The ``Session`` model
 | |
| is defined in ``django/models/core.py``. Because it's a normal model, you can
 | |
| access sessions using the normal Django database API::
 | |
| 
 | |
|     >>> from django.models.core import sessions
 | |
|     >>> s = sessions.get_object(pk='2b1189a188b44ad18c35e113ac6ceead')
 | |
|     >>> s.expire_date
 | |
|     datetime.datetime(2005, 8, 20, 13, 35, 12)
 | |
| 
 | |
| Note that you'll need to call ``get_decoded()`` to get the session dictionary.
 | |
| This is necessary because the dictionary is stored in an encoded format::
 | |
| 
 | |
|     >>> s.session_data
 | |
|     'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...'
 | |
|     >>> s.get_decoded()
 | |
|     {'user_id': 42}
 | |
| 
 | |
| When sessions are saved
 | |
| =======================
 | |
| 
 | |
| By default, Django only saves to the session database when the session has been
 | |
| modified -- that is if any of its dictionary values have been assigned or
 | |
| deleted::
 | |
| 
 | |
|     # Session is modified.
 | |
|     request.session['foo'] = 'bar'
 | |
| 
 | |
|     # Session is modified.
 | |
|     del request.session['foo']
 | |
| 
 | |
|     # Session is modified.
 | |
|     request.session['foo'] = {}
 | |
| 
 | |
|     # Gotcha: Session is NOT modified, because this alters
 | |
|     # request.session['foo'] instead of request.session.
 | |
|     request.session['foo']['bar'] = 'baz'
 | |
| 
 | |
| **Only available in Django development version.** To change this default
 | |
| behavior, set the ``SESSION_SAVE_EVERY_REQUEST`` setting  to ``True``. If
 | |
| ``SESSION_SAVE_EVERY_REQUEST`` is ``True``, Django will save the session to the
 | |
| database on every single request.
 | |
| 
 | |
| Note that the session cookie is only sent when a session has been created or
 | |
| modified. If ``SESSION_SAVE_EVERY_REQUEST`` is ``True``, the session cookie
 | |
| will be sent on every request.
 | |
| 
 | |
| Similarly, the ``expires`` part of a session cookie is updated each time the
 | |
| session cookie is sent.
 | |
| 
 | |
| Settings
 | |
| ========
 | |
| 
 | |
| A few `Django settings`_ give you control over session behavior:
 | |
| 
 | |
| SESSION_COOKIE_AGE
 | |
| ------------------
 | |
| 
 | |
| Default: ``1209600`` (2 weeks, in seconds)
 | |
| 
 | |
| The age of session cookies, in seconds.
 | |
| 
 | |
| SESSION_COOKIE_DOMAIN
 | |
| ---------------------
 | |
| 
 | |
| Default: ``None``
 | |
| 
 | |
| The domain to use for session cookies. Set this to a string such as
 | |
| ``".lawrence.com"`` for cross-domain cookies, or use ``None`` for a standard
 | |
| domain cookie.
 | |
| 
 | |
| SESSION_COOKIE_NAME
 | |
| -------------------
 | |
| 
 | |
| Default: ``'sessionid'`` (**Django development version.** Previous default was
 | |
| ``'hotclub'``, which was deemed too pornish.)
 | |
| 
 | |
| The name of the cookie to use for sessions. This can be whatever you want.
 | |
| 
 | |
| SESSION_SAVE_EVERY_REQUEST
 | |
| --------------------------
 | |
| 
 | |
| Default: ``False``
 | |
| 
 | |
| **Only available in Django development version.**
 | |
| 
 | |
| Whether to save the session data on every request. If this is ``False``
 | |
| (default), then the session data will only be saved if it has been modified --
 | |
| that is, if any of its dictionary values have been assigned or deleted.
 | |
| 
 | |
| .. _Django settings: http://www.djangoproject.com/documentation/settings/
 | |
| 
 | |
| Technical details
 | |
| =================
 | |
| 
 | |
|     * The session dictionary should accept any pickleable Python object. See
 | |
|       `the pickle module`_ for more information.
 | |
| 
 | |
|     * Session data is stored in a database table named ``core_sessions`` .
 | |
| 
 | |
|     * Django only sends a cookie if it needs to. If you don't set any session
 | |
|       data, it won't send a session cookie.
 | |
| 
 | |
| .. _`the pickle module`: http://www.python.org/doc/current/lib/module-pickle.html
 | |
| 
 | |
| Session IDs in URLs
 | |
| ===================
 | |
| 
 | |
| The Django sessions framework is entirely, and solely, cookie-based. It does
 | |
| not fall back to putting session IDs in URLs as a last resort, as PHP does.
 | |
| This is an intentional design decision. Not only does that behavior make URLs
 | |
| ugly, it makes your site vulnerable to session-ID theft via the "Referer"
 | |
| header.
 |