Are class based views shared between requests?

11 views
Skip to first unread message

Tigra

unread,
Jul 28, 2012, 12:00:37 PM7/28/12
to kay-...@googlegroups.com
Hi guys, i have following question:

Is it safe to put context variable into my base View class(other extends it) like this?

class MainPage(BaseHandler):
    context={}
    def prepare(self):
        self.context=dict()
        self.context['IN_PRODUCTION']=is_in_production

After that some View can do following:
class AnotherView(MainPage):
 def get(self,some_key):
  self.context['some_object']=SomeModel.get(some_key) # ROW A
  return render_to_response("view.html",self.context) # ROW B

So the question is, can it be ever possible, that race condition occurs in ROW A and context from other(or more bad, from other view and other user) passed into template?
I afraid, that if View class is shared between requests this situation is possible.

Prateek Malhotra

unread,
Jul 30, 2012, 1:33:33 PM7/30/12
to kay-...@googlegroups.com
How are you specifying your class-based views in your urls.py? Every incoming request should instantiate a new, fresh instance of your class so you shouldn't ever have to worry about local class variables being shared between requests or carrying into future requests.

-Prateek


--
You received this message because you are subscribed to the Google Groups "kay-users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/kay-users/-/pxIOPvxcix0J.
To post to this group, send email to kay-...@googlegroups.com.
To unsubscribe from this group, send email to kay-users+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/kay-users?hl=en.

Anton Bykov

unread,
Jul 30, 2012, 3:12:14 PM7/30/12
to kay-...@googlegroups.com
Like this
    Rule('/', endpoint='index', view=('app.views.Index',(),{})),

So it does not really tell me if it is new instances or shared :)
I had an issue with some other non-gae framework, where instances where shared(this makes sense btw, talking about performance, but some functionality loses)
So highly aware about this matter.

BTW, made some checks now, I am afraid you are wrong and instances are shared (well, at least their common ancestor shared):

Done following:
Have two views, both extend MainPage
Made write to context['from_index'] on index page and read it with another request from another view. 
The data in ['from_index'] was there... So ancestor shared.

So common ancestor cannot be used for storing anything. Only for overriding of pre-defined properties on class level, not on runtime logic.
And I can't find a way to check if race condition can occur inside same view by accessing same variable(e.g. context). A lot in-the-same time request should be made to check this...

Prateek Malhotra

unread,
Jul 30, 2012, 3:34:30 PM7/30/12
to kay-...@googlegroups.com
GAE aside, having one class inherit from another class does not mean that they will share class variable data...

class A(object):
   class_var = {}

class B(A):
   class_var2 = []

obj = B()
obj.class_var = 1
obj2 = A()
print obj2.class_var #This will print '{}'

Inheritance does not mean data between classes is shared, its just the template is copied between the two classes (not 100% accurate but gets the message across). Unless you are dealing with static variables there's no reason why data should be shared among different instances of classes. Can you post your full test code on https://gist.github.com/ or e-mail it to me?

Thanks,
Prateek

Anton Bykov

unread,
Jul 30, 2012, 4:15:32 PM7/30/12
to kay-...@googlegroups.com
Sure

This is blank kay project, with testshared app

Two views, first enter /, then enter /other

And you will see, that data written in Index available at Other view.


P.S kay and manage.py links to ../kay

Anton Bykov

unread,
Jul 30, 2012, 4:29:34 PM7/30/12
to kay-...@googlegroups.com
Update:

context or any other variable should be placed into __init__

class MainPage(BaseHandler):
    template=None

    def __init__(self):
        self.context={}
        super(MainPage,self).__init__()

Instead of first variant

class MainPage(BaseHandler):
    template=None
    context={}

Static(like template) should go into definition, runtime-changed to __init__
With such approach no chances for race condition. Solved :)
The fact that __init__ works proves, that Views are not shared.
But changing of self.anything changes the class itself(as well as inherited), not the object.


On Jul 30, 2012, at 10:34 PM, Prateek Malhotra wrote:

Reply all
Reply to author
Forward
0 new messages