[Zope-Checkins] CVS: Releases/Zope/lib/python/Products/Sessions/help - Sessions.stx:1.3 browser-add.stx:1.4 browser-change.stx:1.3 session-add.stx:1.4 session-change.stx:1.3 sessionapi-prog.stx:1.3 session-admin.stx:NONE
Matthew T. Kromer
matt@zope.com
Wed, 14 Nov 2001 17:09:04 -0500
Update of /cvs-repository/Releases/Zope/lib/python/Products/Sessions/help
In directory cvs.zope.org:/tmp/cvs-serv11360
Modified Files:
Sessions.stx browser-add.stx browser-change.stx
session-add.stx session-change.stx sessionapi-prog.stx
Removed Files:
session-admin.stx
Log Message:
Update session docs; merge two into one (elimininating separate
session-admin doc)
=== Releases/Zope/lib/python/Products/Sessions/help/Sessions.stx 1.2 => 1.3 ===
+Session Administration
Overview
@@ -25,23 +25,197 @@
To facilitate sessions on systems without ZEO, you may wish to create
a *Temporary Folder* to store your Transient Objects.
- Usage
+ The session data manager will begin automatically adding a SESSION
+ object to the REQUEST in the default configuration.
- The simplest way to use sessions is to activate the "Automatic Session"
- feature in the Session Data Manager object. This will cause a session
- object to be fetched or created if necessary and stored in the 'REQUEST'
- object under the name 'SESSION'.
+ Session Data Object Expiration
- This 'SESSION' object behaves as a dictionary, so the following python
- script would demonstrate incrementing a counter in the session::
-
- request = context.REQUEST
- session = request.SESSION
-
- counter = session.get('counter',0) + 1
- session['counter'] = counter
-
- For more advanced programming details, see the *Session API* documentation.
+ Session data objects expire after the period between their last
+ access and "now" exceeds the timeout value provided to the
+ transient object container which hold them. No special action need
+ be taken to expire session data objects.![1]
+
+ ![1] See "Session Data Object Expiration Considerations" in the
+ Concepts and Caveats section below for details on session data
+ expiration.
+
+ Importing And Exporting Session Data Objects
+
+ In some circumstances, it is useful to be able to "export" all
+ the session data from a specific transient object container in order
+ to "import" it to another. This may be necessary when migrating
+ data between containers or when upgrading the session tracking
+ implementation to a more recent version.
+
+ You can export data from a transient object container by visiting
+ its "Advanced" tab, and choosing "Export Session Data". A file
+ will be written to the hard disk of the Zope server you're
+ talking to in the 'var' directory of the Zope instance named
+ "sessiondata.zexp".
+
+ To import exported session data, choose "Import Session Data"
+ from the Advanced tab of the transient object container you're
+ migrating to. The "sessiondata.zexp" file containing the
+ exported session data will be read from disk and placed into the
+ transient object container.
+
+ The contents of RAM-based (internal) transient object containers
+ cannot be exported, and you may not import session data into an
+ internal transient object container.
+
+Concepts and Caveats
+
+ Session Id (Non-)Expiration
+
+ Unlike many other sessioning implementations, core session
+ tracking session tokens (ids) do not actually themselves expire.
+ They persist for as long as their conveyance mechanism allows.
+ For example, a session token will last for as long as the session
+ token cookie persists on the client, or for as long as someone
+ uses a bookmarked URL with a session token in it. The same id
+ will be obtained by a browser id manager on every visit by that
+ client to a site - potentially indefinitely depending on which
+ conveyance mechanisms you use and your configuration for cookie
+ persistence. It may be useful to think of a Zope browser id as
+ a "browser id" for this reason.
+
+ In lieu of exipry of browser ids, the transient object container
+ which holds session data objects implements a policy for data
+ object expiration. If asked for a session data object related
+ to a particular browser id which has been expired by a transient
+ object container, a session data manager will a return a new
+ session data object.
+
+ Session Data Object Expiration Considerations
+
+ Because Zope has no scheduling facility, the sessioning
+ machinery depends on the continual exercising of itself to
+ expire session data objects. If the sessioning machinery is not
+ exercised continually, it's possible that session data
+ objects will stick around longer than the time specified by
+ their transient object container timeout value. For example:
+
+ - User A exercises application machinery that generates a
+ session data object. It is inserted into a transient object
+ container which advertises a 20-minute timeout.
+
+ - User A "leaves" the site.
+
+ - 40 minutes go by with no visitors to the site.
+
+ - User B visits 60 minutes after User A first generated his
+ session data object, and exercises app code which hands out
+ session data objects. *User A's session is expired at this
+ point, 40 minutes "late".*
+
+ Sessioning and Transactions
+
+ The existing transient object container implementations interact
+ with Zope's transaction system. If a transaction is aborted,
+ the changes made to session data objects during the transaction
+ will be rolled back.
+
+ Acquisition-Wrapped Objects
+
+ The sessioning machinery unwraps acquisition-wrapped objects
+ before storing them during a session_data_object.set or
+ session_data_object.__setitem__ operation. Practically, this
+ means you can safely pass acquisition-wrapped objects in to the
+ sessioning machinery (for example, a DTML Document obtained via
+ traversal) as values within a session data object. The stored
+ reference will be to the bare unwrapped object. (new in 0.9)
+
+ Mutable Data Stored Within Session Data Objects
+
+ If you mutate an object stored as a value within a session data
+ object, you'll need to notify the sessioning machinery that the
+ object has changed by calling 'set' or '__setitem__' on the
+ session data object with the new object value. For example::
+
+ session = self.session_data_manager.getSessionData()
+ foo = {}
+ foo['before'] = 1
+ session.set('foo', foo)
+
+ # mutate the dictionary
+
+ foo['after'] = 1
+
+ # performing session.get('foo') 10 minutes from now will likely
+ # return a dict with only 'before' within!
+
+ You'll need to treat mutable objects immutably, instead. Here's
+ an example that makes the intent of the last example work by
+ doing so::
+
+ session = self.session_data_manager.getSessionData()
+ foo = {}
+ foo['before'] = 1
+ session.set('foo', foo)
+
+ # mutate the dictionary
+ foo['after'] = 1
+
+ # tickle the persistence machinery
+ session.set('foo', foo)
+
+ An easy-to-remember rule for manipulating data objects in
+ session storage: always explicitly place an object back into
+ session storage whenever you change it. For further reference,
+ see the "Persistent Components" chapter of the Zope Developer's
+ Guide at http://www.zope.org/Documentation/ZDG.
+
+ Session Data Object Keys
+
+ A session data object has essentially the same restrictions as a
+ Python dictionary. Keys within a session data object must be
+ hashable (strings, tuples, and other immutable basic Python
+ types; or instances which have a __hash__ method). This is a
+ requirement of all Python objects that are to be used as keys to
+ a dictionary. For more information, see the associated Python
+ documentation at
+ http://www.python.org/doc/current/ref/types.html (Mappings ->
+ Dictionaries).
+
+ In-Memory Session Data Container RAM Utilization
+
+ Each session data object which is added to an "internal"
+ (RAM-based) transient object container will consume at least 2K of
+ RAM.
+
+ Mounted Database-Based Session Data Container/Internal Session
+ Data Container Caveats
+
+ Persistent objects which have references to other persistent
+ objects in the same database cannot be committed into a mounted
+ database because the ZODB does not currently handle
+ cross-database references.
+
+ "Internal" (RAM-based) transient object containers are currently
+ implemented as objects within (automatically) mounted ZODB
+ databases. For this reason, they are equivalent in operation to
+ external transient object containers which are placed in a manually
+ mounted database.
+
+ If you use an internal transient object container or an external
+ transient object container that is accessed via a "mounted"
+ database, you cannot store persistent object instances which
+ have already been stored in the "main" database as keys or
+ values in a session data object. If you try to do so, it is
+ likely that an 'InvalidObjectReference' exception will be raised
+ by the ZODB when the transaction involving the object attempts
+ to commit. As a result, the transaction will fail and the
+ session data object (and other objects touched in the same
+ transaction) will fail to be committed to storage.
+
+ If your "main" ZODB database is backed by a nonundoing storage,
+ you can avoid this condition by storing session data objects in
+ an external data container instantiated within the "main" ZODB
+ database. If this is not an option, you should ensure that
+ objects you store as values or keys in a session data object
+ held in a mounted transient object container are instantiated "from
+ scratch" (via their constructors), as opposed to being "pulled
+ out" of the main ZODB.
Networking with ZEO
@@ -52,6 +226,62 @@
thus any session data stored in a Temporary Folder will not be
distributed to other ZEO clients.
+ Conflict Errors
+
+ This session tracking software stores all session state in
+ Zope's ZODB. The ZODB uses an optimistic concurrency strategy
+ to maintain transactional integrity for simultaneous writes.
+ This means that if two objects in the ZODB are changed at the
+ same time by two different connections (site visitors) that a
+ "ConflictError" will be raised. Zope retries requests that
+ raise a ConflictError at most 3 times. If your site is
+ extremely busy, you may notice ConflictErrors in the Zope debug
+ log (or they may be printed to the console from which you run
+ Zope). An example of one of these errors is as follows::
+
+ 2001-01-16T04:26:58 INFO(0) Z2 CONFLICT Competing writes at, /getData
+ Traceback (innermost last):
+ File /zope/lib/python/ZPublisher/Publish.py, line 175, in publish
+ File /zope/lib/python/Zope/__init__.py, line 235, in commit
+ File /zope/lib/python/ZODB/Transaction.py, line 251, in commit
+ File /zope/lib/python/ZODB/Connection.py, line 268, in commit
+ ConflictError: '\000\000\000\000\000\000\002/'
+
+ Errors like this in your debug log (or console if you've not
+ redirected debug logging to a file) are normal to an extent. If
+ your site is undergoing heavy load, you can expect to see a
+ ConflictError perhaps every 20 to 30 seconds. The requests
+ which experience conflict errors will be retried automatically
+ by Zope, and the end user should *never* see one. Generally,
+ session data objects attempt to provide application-level
+ conflict resolution to reduce the limitations imposed by
+ conflict errors NOTE: to take advantage of this feature, you
+ must be running Zope 2.3.1 or better, and you must be using it
+ with a storage such as FileStorage or SessionStorage which
+ supports application-level conflict resolution.
+
+Zope Versions and Sessioning
+
+ Zope Versions are not particularly useful in combination with
+ sessioning. Particularly, if you change the properties of a
+ session data manager or browser id manager while working in a
+ Version on a "production" site, it may cause the sessioning
+ machinery to stop working for unversioned visitors to the site
+ due to the "locking" nature of versions. To work around this
+ problem, do not lock any sessioning-related objects while in a
+ Version. Alternately, do not use Versions.
+
+Extending The Session Tracking Product
+
+ Implementing Alternate Session Data Managers and Data Containers
+
+ Alternate session data managers and data containers (perhaps
+ using a SQL database as a persistence mechanism) may be
+ implemented if they adhere to the interfaces outlined in the
+ SessioningInterfaces.py documentation which ships with this
+ software.
+
+
See Also
- "Transient Objects":../../Transience/Help/Transience.stx
@@ -61,5 +291,3 @@
- "Session API":SessionInterfaces.py
- "Session API Programming":sessionapi-prog.stx
-
- - "Session Administration":session-admin.stx
=== Releases/Zope/lib/python/Products/Sessions/help/browser-add.stx 1.3 => 1.4 ===
- "Session Tracking":Sessions.stx
- - "Session Administration":session-admin.stx
-
=== Releases/Zope/lib/python/Products/Sessions/help/browser-change.stx 1.2 => 1.3 ===
- "Session Tracking":Sessions.stx
- - "Session Administration":session-admin.stx
=== Releases/Zope/lib/python/Products/Sessions/help/session-add.stx 1.3 => 1.4 ===
- "Session Tracking":Sessions.stx
- - "Session Administration":session-admin.stx
=== Releases/Zope/lib/python/Products/Sessions/help/session-change.stx 1.2 => 1.3 ===
- "Session Tracking":Sessions.stx
- - "Session Administration":session-admin.stx
=== Releases/Zope/lib/python/Products/Sessions/help/sessionapi-prog.stx 1.2 => 1.3 ===
+
Overview
- Developers generally interact with a Session Data Manager
- instance in order to make use of sessioning in Zope. Methods
- named in this section are those of session data managers unless
- otherwise specified.
-
- All of the methods implemented by Session Data Managers, Session
- Id Managers and Session Data objects are fully documented in the
- "SessioningInterfaces.py" file accompanying this software.
- This section of the documentation will concentrate on explaining
- common operations having to do with session-tracking and why
- they might be important to you.
-
- Terminology
-
- Here's a mini-glossary of terminology used by the session
- tracking product:
-
- token (aka 'token value') -- the string or integer used to
- represent a single anonymous visitor to the part of the Zope
- site managed by a single session id manager.
- E.g. "12083789728".
-
- token key namespaces -- the session token key/value pair will
- be found in one of these namespaces. They refer to namespaces
- codified in the Zope REQUEST object. E.g. "cookies" or
- "form".
-
- token key -- the key which is looked for in the REQUEST
- namespaces enumerated by the token key namespaces configured.
- This references the token as its value. E.g. "_ZopeId".
-
- session data object -- an instance of the session data object
- class that is found by asking a transient object container for the
- item with a key that is a token value.
-
- Obtaining the Token Value
-
- You can obtain the token value associated with the current
- request from a session data manager::
-
- <dtml-var "sessiondatamanager.getToken()">
-
- This snippet will print the token value to the remote browser.
- If no token exists for the current request, a new token is
- created implicitly and returned.
-
- If you wish to obtain the current token value without implicitly
- creating a new token for the current request, you can use the
- 'create' argument to the 'getToken()' method to suppress this
- behavior::
-
- <dtml-var "sessiondatamanager.getToken(create=0)">
-
- This snippet will print a representation of the None value if
- there isn't a session token associated with the current request,
- or it will print the token value if there is one associated with
- the current request. Using 'create=0' is useful if you do not
- wish to cause the sessioning machinery to attach a new session
- token to the current request, perhaps if you do not wish a
- session cookie to be set.
-
- The token value *is not* the session data. The token value
- represents the key by which the 'getSessionData' method obtains
- a session data object representing the visitor marked by the
- token. The token value is either a string or an integer and has
- no business meaning. In your code, you should not rely on the
- session token composition, length, or type as a result, as it is
- subject to change.
-
- Determining Which Token Key Namespace Holds The Session Token
-
- For some applications, it is advantageous to know from which
- token key namespace (currently either 'cookies' or 'form') the
- token has been gathered. There are two methods of session data
- managers which allow you to accomplish this,
- 'isTokenFromCookie()', and 'isTokenFromForm()'::
-
- <dtml-if "sessiondatamanager.isTokenFromCookie()">
- The token came from a cookie.
- </dtml-if>
-
- <dtml-if "sessiondatamanager.isTokenFromForm()">
- The token came from a form.
- </dtml-if>
-
- The 'isTokenFromCookie()' method will return true if the token
- in the current request comes from the 'REQUEST.cookies'
- namespace. This is true if the token was sent to the Zope
- server as a cookie.
-
- The 'isTokenFromForm()' method will return true if the token in
- the current request comes from the 'REQUEST.form' namespace.
- This is true if the token key/value pair was sent to the Zope
- server encoded in a URL or as part of a form element.
-
- If a token doesn't actually exist in the current request when
- one of these methods is called, an error will be raised.
-
- During typical operations, you shouldn't need to use these
- methods, as you shouldn't care from which REQUEST namespace the
- token key/value pair was obtained. However, for highly
- customized applications, this pair of methods may be useful.
-
- Obtaining the Token Key/Value Pair and Embedding It Into A Form
-
- You can obtain the "token key" from a session data manager
- instance. The token key is the name which is looked for in
- token key namespaces by a session id manager. We've already
- determined how to obtain the token value. It is useful to
- obtain the token key/value pair if you wish to embed a session
- token key/value pair as a hidden form field for use in POST
- requests::
-
- <html>
- <body>
- <form action="thenextmethod">
- <input type=submit name="submit" value=" GO ">
- <input type=hidden name="<dtml-var "sessiondatamanager.getTokenKey()">"
- value="<dtml-var "sessiondatamanager.getToken()">">
- </form>
- </body>
- </html>
-
- Determining Whether A Session Token is "New"
-
- A session token is "new" if it has been set in the current
- request but has not yet been acknowledged by the client --
- meaning it has not been sent back by the client in a request.
- This is the case when a new session token is created by the
- sessioning machinery due to a call to 'getSessionData()' or
- similar as opposed to being received by the sessioning machinery
- in a token key namespace. You can use the 'isTokenNew()' method
- of session data managers to determine whether the session is
- new::
-
- <dtml-if "sessiondatamanager.isTokenNew()">
- Token is new.
- <dtml-else>
- Token is not new.
- </dtml-if>
-
- This method may be useful in cases where applications wish to
- prevent or detect the regeneration of new tokens when the same
- client visits repeatedly without sending back a token in the
- request (such as may be the case when a visitor has cookies
- "turned off" in their browser and the session id manager only
- uses cookies).
-
- If there is no session token associated with the current
- request, this method will raise an error.
-
- You shouldn't need to use this method during typical operations,
- but it may be useful in advanced applications.
-
- Determining Whether A Session Data Object Exists For The Token Associated
- With This Request
-
- If you wish to determine whether a session data object with a
- key that is the current request's token exists in the data
- manager's associated transient object container, you can use the
- 'hasSessionData()' method of the session data manager. This
- method returns true if there is session data associated with the
- current session token::
-
- <dtml-if "sessiondatamanager.hasSessionData()">
- The sessiondatamanager object has session data for the token
- associated with this request.
- <dtml-else>
- The sessiondatamanager object does not have session data for
- the token associated with this request.
- </dtml-if>
-
- The 'hasSessionData()' method is useful in highly customized
- applications, but is probably less useful otherwise. It is
- recommended that you use 'getSessionData()' instead, allowing
- the session data manager to determine whether or not to create a
- new data object for the current request.
-
- Embedding A Session Token Into An HTML Link
-
- You can embed the token key/value pair into an HTML link for use
- during HTTP GET requests. When a user clicks on a link with a
- URL encoded with the session token, the token will be passed
- back to the server in the REQUEST.form namespace. If you wish
- to use formvar-based session tracking, you will need to encode
- all of your "public" HTML links this way. You can use the
- 'encodeUrl()' method of session data managers in order to
- perform this encoding::
-
- <html>
- <body>
- <a href="<dtml-var "sessiondatamgr.encodeUrl('/amethod')">">Here</a>
- is a link.
- </body>
- </html>
-
- The above dtml snippet will encode the URL "/amethod" (the
- target of the word "Here") with the session token key/value pair
- appended as a query string. You can additionally pass URLs
- which already contain query strings to the 'encodeUrl()' method
- successfully.
-
- Obtaining A Session Data Object
-
- Use the 'getSessionData()' method of session data managers to
- obtain the session data object associated with the session token
- in the current request::
-
- <dtml-let data="sessiondatamanager.getSessionData()">
- The 'data' name now refers to a new or existing session data object.
- </dtml-let>
-
- The 'getSessionData()' method implicitly creates a new session
- token and data object if either does not exist in the current
- request. To inhibit this behavior, use the create=0 flag to the
- 'getSessionData()' method::
-
- <dtml-let data="sessiondatamanager.getSessionData(create=0)">
- The 'data' name now refers to an existing session data object or
- None if there was no existing token or session data object.
- </dtml-let>
-
- The 'getSessionData()' method is a highly used method. It is
- probably the most-commonly used method of session data managers.
-
- Modifying A Session Data Object
-
- Once you've used 'getSessionData()' to obtain a session data
- object, you can set key/value pairs of the returned session data
- object. These key/value pairs are where you store information
- related to a particular anonymous visitor. You can use the
- 'set', 'get', and 'has_key' methods of session data objects to
- perform actions related to it::
-
- <dtml-let data="sessiondatamanager.getSessionData()">
- <dtml-call "data.set('foo', 'bar')">
- <dtml-comment>Set 'foo' key to 'bar' value.</dtml-comment>
- <dtml-var "data.get('foo')">
- <dtml-comment>Will print 'bar'</dtml-comment>
- <dtml-if "data.has_key('foo')">
- This will be printed.
- <dtml-else>
- This will not be printed.
- </dtml-if>
- </dtml-let>
-
- An essentially arbtrary set of key/value pairs can be placed
- into a session data object. Keys and values can be any kinds of
- Python objects (note: see Concepts and Caveats section for
- exceptions to this rule). The transient object container which
- houses the session data object determines its expiration policy.
- Session data objects will be available across client requests
- for as long as they are not expired.
-
- Manually Invalidating A Session Data Object
-
- Developers can manually invalidate a session data object. When
- a session data object is invalidated, it will be flushed from
- the system, and will not be returned on subsequent requests to
- 'getSessionData()'. The 'invalidate()' method of a session data
- object causes this to happen::
-
- <dtml-let data="sessiondatamanager.getSessionData()">
- <dtml-call "data.invalidate()">
- </dtml-let>
-
- Subsequent calls to 'getSessionData()' in this same request will
- return a new session data object. Manual invalidation of
- session data is useful in cases where you know the session data
- is stale and you wish to flush it from the data manager.
-
- Manually Invalidating A Session Token Cookie
-
- Developers may manually invalidate the cookie associated with
- the session token, if any. To do so, they can use the
- 'flushTokenCookie()' method of a session data manager. For
- example::
-
- <dtml-call "sessiondatamanager.flushTokenCookie()">
-
- If the 'cookies' namespace isn't a valid token key namespace
- when this call is performed, an exception will be raised.
-
- An Example Of Using Session Data from DTML
-
- An example of obtaining a session data object from a session
- data manager named 'sessiondatamgr' and setting one of its
- key-value pairs in DTML follows::
-
- <dtml-with sessiondatamgr>
- <dtml-let a=getSessionData>
- Before change: <dtml-var a><br>
- <dtml-call "a.set('zopetime', ZopeTime())">
- <dtml-comment>
- 'zopetime' will be set to a datetime object for the current
- session
- </dtml-comment>
- After change: <dtml-var a><br>
- </dtml-let>
- </dtml-with>
-
- The first time you run this method, the "before change"
- representation of the session data object will be that of an
- empty dictionary, and the "after change" representation will
- show a key/value pair of 'zopetime' associated with a DateTime
- object. Assuming you've configured your session id manager with
- cookies and they're working on your browser properly, the second
- and subsequent times you view this method, the "before change"
- representation of the session data object will have a datetime
- object in it that was the same as the last call's "after change"
- representation of the same session data object. This
- demonstrates the very basics of session management, because it
- demonstrates that we are able to associate an object (the
- session data object obtained via getSessionData) with an
- anonymous visitor between HTTP requests.
-
- NOTE: To use this method in conjunction with formvar-based
- sessioning, you'd need to encode a link to its URL with the
- session token by using the session data manager's 'encodeUrl()'
- method.
-
- Using the 'mapping' Keyword With A Session Data Object in a 'dtml-with'
-
- DTML has the facility to treat a session data object as a
- mapping, making it easier to spell some of the more common
- methods of access to session data objects. The 'mapping'
- keyword to dtml-with means "treat name lookups that follow
- this section as queries to my contents by name." For
- example::
-
- <dtml-let a="sm.getSessionData()">
- <dtml-call "a.set('zopetime', ZopeTime())">
- <dtml-comment>
- 'zopetime' will be set to a datetime object for the current
- session... the "set" it calls is the set method of the
- session data object.
- </dtml-comment>
- </dtml-let>
-
- <dtml-with "sm.getSessionData()" mapping>
- <dtml-var zopetime>
- <dtml-comment>
- 'dtml-var zopetime' will print the DateTime object just set
- because we've used the mapping keyword to map name lookups
- into the current session data object.
- </dtml-comment>
+ Developers generally *not* interact directly with a Session Data
+ Manager instance in order to make use of sessioning in Zope.
+
+ All of the methods implemented by Session Data Managers, and
+ Browser Id Managers are fully documented in the
+ Session API in the "See Also" section below.
+
+ Common Programming
+
+ Generally, instead of directly interacting with the session data
+ manager, you use it's built in traversal feature to put a SESSION
+ object in the REQUEST. This is simple, and fairly intuitive.
+ For example, in DTML you might::
+
+ <dtml-with SESSION mapping>
+ <dtml-var cart missing="You have no cart">
</dtml-with>
- Using Session Data From Python
+ or even more simply::
+
+ <dtml-var SESSION>
+
+ This would print the cart object in the session, or the entire SESSION
+ object. You could set an
+ object in the session similarly to how you set it in the REQUEST::
+
+ <dtml-call expr="SESSION.set('cart','this is really more of a wagon')">
+
+ You adjust the name of the SESSION object in the management screens
+ for the session data object. You can do more complex operations on
+ SESSION data with python scripts, e.g.::
+
+ session = context.REQUEST.SESSION
+
+ cart = session.get('cart',()) # Get our cart or an empty list
+ cart.append(('my line item',100.00))
+
+ session['cart'] = cart # force a save back to the session
+
+
+ In general, it is better to put manipulation of data in the session in
+ a python script than it is to do it via DTML or a page template; while
+ the latter is possible, it would be far better to simply place a session
+ management call at the top of any page which requires manipulation of
+ session data.
+
+ Tips
- Here's an example of using a session data manager and session
- data object from a set of Python external methods::
+ Keep in mind that SESSION objects (Which are really Transient Objects)
+ are basically dictionaries; if you wish to iterate through them in the
+ context of a DTML-IN expression, you should use something like::
- import time
- def setCurrentTime(self):
- sessiondatamgr = self.sessiondatamgr
- a = sessiondatamgr.getSessionData()
- a.set('thetime', time.time())
-
- def getLastTime(self):
- sessiondatamgr = self.sessiondatamgr
- a = sessiondatamgr.getSessionData()
- return a.get('thetime')
+ <dtml-in expr="SESSION.items()">
+ <dtml-var sequence-key>: <dtml-var sequence-item>
+ </dtml-in>
See Also
@@ -372,4 +65,4 @@
- "Session Tracking":Sessions.stx
- - "Session Administration":session-admin.stx
+ - "Transient Object API":../../Transience/Help/TransienceInterfaces.py
=== Removed File Releases/Zope/lib/python/Products/Sessions/help/session-admin.stx ===