Am 01.10.2010 um 18:07 schrieb Luke Plant:

> On Fri, 2010-10-01 at 12:16 +0200, Johannes Dollinger wrote:
>> Am 01.10.2010 um 07:26 schrieb Russell Keith-Magee:
>>> I've just added a summary of the last thread on class-based views
>> [1].
>>> This summary isn't 100% complete -- any contributions from
>> interested
>>> parties are welcome. Try to keep opinions to a minimum; this page is
>>> about documenting the strengths and weaknesses of various
>> approaches,
>>> not about expressing opinions. In the same way that CSRF [2] and
>>> session-messages [3] have good wiki pages describing the design
>>> considerations, we need to be able to explain to future generations
>>> why class-based views are the way they are.
>> 
>> Could you (or anyone knowledgable) add a section, that explains why
>> each request should have its own view instance?
>> The thread-safety argument alone does not suffice: if all _request_
>> state would be stored on request instead of the view, you wouldn't
>> need new instances per request. You could also pass around state
>> explicitly - which admittedly gets messy quickly.
>> So is this purely about preventing users from shooting themselves in
>> the foot? (hyperbole: Will there be protection from globals in django
>> 1.4?)
> 
> It's not just about stopping users from shooting themselves in the foot,
> it's about helping them to do the right thing easily.  Without this kind
> of protection, it will be harder for *anyone*, including experienced
> developers who are aware of the problem, to do things correctly. It's
> like the autoescaping in templates - I *know* that I should use the
> 'escape' filter, but without autoescaping it is hard for anyone to do it
> right all the time.
> 
> One alternative that has been suggested is to pass state around
> explicitly, which is definitely best practice, but in many cases might
> not be possible (e.g. if you are working with someone else's base class,
> and in one overridden method you want to set up some objects which ought
> to be available to other methods). You could also attach stateful data
> to the request object, but attaching random bits of data to the request
> is surely just as ugly a solution as the self.copy() call, especially if
> you need to avoid names clashes with all the other attributes attached
> to request.
> 
> With regards to doing a shallow copy, it should be noted that at the
> point the copy is made, the only data attached to the object is data
> that has been attached in the constructor. It is of course possible that
> methods within the view might mutate such data, but it seems more likely
> that it will be used as immutable configuration data. 
> 
> However, I have already seen some example code that might fall foul of
> this problem - someone gave the example of storing a queryset on the
> object in the __init__. This will get implicitly mutated (the cache is
> filled) when it is used the first time. This could lead to frustrating
> problems that wouldn't be found in testing, and doing copy() on the
> instance won't help.
> 
> So, in light of the fact that developers *will* need to be aware of this
> issue, I'd like to tentatively suggest an explicit solution which is
> nonetheless easy to use and get right. We could have an explicit 'state'
> object that is thrown away for every new request, something like this:
> 
> class State(object):
>    pass
> 
> class View(object):
>    def __call__(self, request, *args, **kwargs):
>        """
>        Main entry point for a request-response process.
>        """
>        self.state = State()
>        self.request = request
>        self.args = args
>        self.kwargs = kwargs
>        resp = self.dispatch(request, *args, **kwargs)
>        # let any state get GC'd immediately:
>        del self.state 
>        del self.request
>        del self.args
>        del self.kwargs
>        return resp
> 
> We document the issue, warn people not to store state on the instance
> itself, but tell them that if they must have stateful data, it should be
> attached to self.state instead of self, and they will be OK.  They might
> still be bitten if they put mutable configuration data into the __init__
> and it gets mutated, but we have made it easy to do the right thing -
> doing 'self.state.x' is only slightly harder than 'self.x'
> 
> Thoughts?


If you are willing to limit view state to a dedicated container, you might as 
well put in on request (e.g. request.view, request.state, request.context, ...) 
- and store args/kwargs in it as well.
There would be no need to copy or clear self. It could be added automatically 
for all views (even those that are plain functions).

However, I am -0 on the self.copy() proposal. While I believe it's the wrong 
design decision, I'd be happy with any decision at this point.
__
Johannes

                

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to