Thanks for clarifying, I see where my initial confusion was now. The reason this leak hadn't affected our apps was because we didn't use __init__ to set up the view, instead all the state logic was placed into __call__. Never the less, having a class call return a HTTPResponse will break class usage expectations (as mentioned in the wiki), so this still wouldn't be the cleanest approach.
I think the majority of users seem to be put off by the complexity of using ListView/TemplateView, and not the actual class usage itself. If the documentation highlighted that there was a basic View() object available, it would make the learning curve a bit easier. Russell - Would you have any objection to me submitting a documentation patch (https://docs.djangoproject.com/en/1.4/topics/class-based-views/) which shows a basic example of how to use the View() class directly? Cal On Wed, Sep 19, 2012 at 12:45 AM, Russell Keith-Magee < russ...@keith-magee.com> wrote: > On Tue, Sep 18, 2012 at 7:24 PM, Cal Leeming [Simplicity Media Ltd] > <cal.leem...@simplicitymedialtd.co.uk> wrote: > > Russell, > > > > On a separate note, I am curious about these 'copy-on-call' leaks, and I > > have not seen this behaviour documented anywhere else. > > > > "The abstraction of the copy-on-call can leak in surprising ways. Some > users > > will try to set up state using an __init__ method (common practice). If > any > > of the state they attach to self in __init__ is mutable (list, dict, > object, > > etc) and they mutate it in the view, this will fail (but not > immediately, or > > in obvious ways)." > > > > Could you elaborate further on this, possibly with a rough example? > > > > Not arguing that CBV approach should be changed, but this copy-on-call > > behaviour is quite unexpected, no? > > The issue is the shallow copy. > > You create a view that sets up state in the __init__ method. Part of > your view's state is held in a mutable object (e.g., a dict, list or > object). The __call__ creates a shallow copy of the view object. A > shallow copy of a mutable object copies the container, but the new > container points to the old content. > > So, if your view logic modifies something held by the mutable object > (which will be a fairly common occurrence), the modification will be > shared by all instances of your view. Hilarity ensues :-) > > You could work around this by using a deep copy, but then you're into > territory where accessing a view could be an incredibly expensive > operation, which is something we want to avoid. It also means anything > you attach to a view must be deep-copyable, which won't always be > true. > > Yours, > Russ Magee %-) > > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To post to this group, send email to django-users@googlegroups.com. > To unsubscribe from this group, send email to > django-users+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/django-users?hl=en. > > -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.