0

i noticed a strange behaviour when interacting with session variables in Django. In one of my app i created a middleware.py file containing a function that copy a session variable that stores an object into a local one and then i change an attribute of the object from the local var. It happens that the changes i make to the local variable are applied also to the session variable. It seems that the local var is only a reference to the session. Is this behaviour correct? Here's the code:

class CloudMiddleware(object):
    user = request.session['user']
    user.email = 'myemail'

When i do

user = request.session['user']
email = user.email

The value of email is equal to 'myemail'. I always thought i had to save my object back in the session if i want to store it. Could someone explain me how it really works?

2 Answers2

1

user is a mutable object, so it's passed by reference. Anything is correct.

DrTyrsa
  • 31,014
  • 7
  • 86
  • 86
1

This is nothing to do with sessions, but a simple consequence of how Python mutable objects work. When you do user = request.session['user'] you are getting a reference to the object, exactly as you would with any other mutable object stored in a standard dictionary. So yes, when you change one of its attributes, that change is referenced in any other reference you have to it.

Note that for sessions, this change will only be persisted in the lifetime of the current request. That's because Django can't know the session object has changed, so won't save it unless you specifically tell it to - see the documentation for details.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Thank you! I'm new to Python and Django and i have never heard of mutable objects. Can you suggest a good guide that explains python in details? – MarcoNegro Sep 27 '11 at 10:01
  • "Mutable" just means changeable - ie lists or dicts are mutable, because you can modify their contents. Ints, strings and tuples are not mutable, because you can't modify them - you can only rebind the variable to a different one. [This answer](http://stackoverflow.com/questions/986006/python-how-do-i-pass-a-variable-by-reference#answer-986145) looks like a good summary. – Daniel Roseman Sep 27 '11 at 10:10