On Oct 3, 1:02 pm, Russell Keith-Magee <russ...@keith-magee.com> wrote: > On Sun, Oct 3, 2010 at 12:12 PM, Ian Lewis <ianmle...@gmail.com> wrote: > > On Sun, Oct 3, 2010 at 11:20 AM, Russell Keith-Magee > > <russ...@keith-magee.com> wrote: > > While I'm in the "one singleton view instance is best" camp and think > > that storing some state on the request and some on the view is a bit > > gross, I understand Russell's arguments. New users are simply going to > > save stuff on self no matter how much we complain, document etc. It's > > simply a reality that likely can't be helped much. > > > Other frameworks seem have View/Handler instances per request, such as > > appengine's webapp so there is some precedent for creating an instance > > per request. > > >http://code.google.com/appengine/docs/python/gettingstarted/handlingf... > > I don't think you'll find any argument that having an instance per > request would solve all the problems that this thread has described. > The issue is how to declare a view that is able to be instantiated on > a instance-per-request basis while simultaneously allowing decorators > to be easily wrapped around that view. > > Yours, > Russ Magee %-)
I haven't investigated the other solutions described in this discussion, but the solution I proposed handles decorators just fine. Furthermore, you can extend it to allow for decorators by subclassing. Initial code: class BaseView(object): def __new__(cls, *args, **kwargs): obj = super(BaseView, cls).__new__(cls) # Call __init__ manually since it will not be called # after this method (since __new__ returns a HttpResponse # and not a BaseView subclass). obj.__init__(*args, **kwargs) return obj.view() # Or other name class MyView(BaseView): def __init__(self, request): self.request = request def view(self): return HttpResponse(self.request.path) urlpatterns = patterns("", ("^login_required_view/$", login_required(MyView))) This will create a view that requires login. We can extend this by introducing a helper function class_decorator that takes a regular decorator and turns it into a view class: def class_decorator(decorator): class Cls(BaseView): def __new__(cls, *args, **kwargs): def view(*args, **kwargs): return super(Cls, cls).__new__(cls, *args, **kwargs) return decorator(view)(*args, **kwargs) return Cls We can then create a LoginRequiredView for instance: LoginRequiredView = class_decorator(login_required) class MyView2(LoginRequiredView): def __init__(self, request): self.request = request def view(self): return HttpResponse(self.request.path) MyView2 functions like login_required(MyView). We can also chain decorators by multiple inheritance. AUsersView = class_decorator(user_passes_test(lambda u: "a" in u.username.lower())) class MyView3(LoginRequiredView, AUsersView): """ View that requires users to be logged in and have a username that contain an 'a'. """ def __init__(self, request): self.request = request def view(self): return HttpResponse(self.request.path) Best regards, André Eriksson -- 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.