Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
#6735 -- Class based generic views: call for comment
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  Messages 1 - 25 of 103 - Collapse all  -  Translate all to Translated (View all originals)   Newer >
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Russell Keith-Magee  
View profile  
 More options Oct 1 2010, 1:26 am
From: Russell Keith-Magee <russ...@keith-magee.com>
Date: Fri, 1 Oct 2010 13:26:12 +0800
Local: Fri, Oct 1 2010 1:26 am
Subject: #6735 -- Class based generic views: call for comment
Hi all,

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.

Based on the discussion on the most recent thread [4], plus in-person
discussions, I'm proposing that we move forward with Ben Firshman and
David Larlet's "__call__ + copy()" approach. Yes, the copy() is a bit
of a weird idiom, but it's not an idiom that users need to be
particularly concerned with; the code "just works" in an unsurprising
way. The other viable option is the __new__ based copy; however, this
approach is also idiomatically surprising (instantiation returns an
object of type other than the object being constructed), and it
doesn't allow for the use of arguments at time of instantiation.

I'd like to try and get this in for 1.3. It's a big feature, which
means it needs to be in by October 18. However, based on the state of
the patch that Ben has prepared, I think this is an achievable goal.

Three things are required to make this happen:

 * Documentation. It looks like David Larlet has made a start on this
already, but there's lots more required.
 * Conversion of the github project into a patch on trunk.
 * Feedback on the API, especially the generic view replacements.

If you have any feedback, drop it into this thread so that we can
integrate the changes. If you are interested in helping out on the
first two points, drop a line here too so that we can coordinate
activity.

I already have one specific piece of API feedback: the current
implementation requires that all view logic is contained in GET(),
POST() etc style views. This is fine, except for the fact that there
are occasions where GET and POST share a lot of common logic. It would
make sense to me to allow for a request() method that is the direct
analog of how we do views right now, wrapping lines 53-59 of base.py
into a request() method. This would allow users to define their own
dispatch mechanisms, or share logic between GET and POST (and any
other http method) as necessary.

[1] http://code.djangoproject.com/wiki/ClassBasedViews
[2] http://code.djangoproject.com/wiki/CsrfProtection
[3] http://code.djangoproject.com/wiki/SessionMessages
[4] http://groups.google.com/group/django-developers/browse_thread/thread...

Yours,
Russ Magee %-)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Santiago Perez  
View profile  
 More options Oct 1 2010, 1:58 am
From: Santiago Perez <san...@santip.com.ar>
Date: Fri, 1 Oct 2010 02:58:12 -0300
Local: Fri, Oct 1 2010 1:58 am
Subject: Re: #6735 -- Class based generic views: call for comment

> I already have one specific piece of API feedback: the current
> implementation requires that all view logic is contained in GET(),
> POST() etc style views. This is fine, except for the fact that there
> are occasions where GET and POST share a lot of common logic. It would
> make sense to me to allow for a request() method that is the direct
> analog of how we do views right now, wrapping lines 53-59 of base.py
> into a request() method. This would allow users to define their own
> dispatch mechanisms, or share logic between GET and POST (and any
> other http method) as necessary.

I'm currently using a very similar approach for class-based views except in
my request() implementation I use the request.method and look at self for an
attribute with the method name uppercased. if it isn't found an
HttpResponseNotAllowed is returned and the list of permited methods is built
from checking the view instance for the known methods. Here's an example of
the constructor and request implementations: http://gist.github.com/605801 .
I have simplified my code for clarity so I may have introduced some bugs.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Hanne Moa  
View profile  
 More options Oct 1 2010, 5:12 am
From: Hanne Moa <hanne....@gmail.com>
Date: Fri, 1 Oct 2010 11:12:47 +0200
Local: Fri, Oct 1 2010 5:12 am
Subject: Re: #6735 -- Class based generic views: call for comment
On 1 October 2010 07:26, Russell Keith-Magee <russ...@keith-magee.com> wrote:

> I already have one specific piece of API feedback: the current
> implementation requires that all view logic is contained in GET(),
> POST() etc style views. This is fine, except for the fact that there
> are occasions where GET and POST share a lot of common logic.

This! is! Python! Any shared logic can be in another method, or
function for that matter, and need not be canonicalized in an API. All
that would be needed is an example in the docs:

class TheView(views.ClassView):

....def _common(self, bla):
........# set up models, forms, other preprocessing here
........# return models/forms or set them on class
........# could be run from __init__  or __new__ or whatever we wind up with

....def GET(self, bla):
........self._common(bla)

....def POST(self, bla):
........self._common(bla)

(Indent-dots to make surer that gmail doesn't meddle with the text.)

Surely class-based views shouldn't disallow methods not named nor
given meaning in an API? Since you needed to explicitly wish for a
specific method, that's how it can be interpreted.

HM


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Luke Plant  
View profile  
 More options Oct 1 2010, 6:17 am
From: Luke Plant <L.Plant...@cantab.net>
Date: Fri, 01 Oct 2010 11:17:10 +0100
Local: Fri, Oct 1 2010 6:17 am
Subject: Re: #6735 -- Class based generic views: call for comment

Passing things around between '_common' and GET and POST makes a simple
view much more complex than it needs to be, especially when you have
various local variables that you now have to assign in some way. In the
end you will end up just routing it all to the one method:

....def GET(self, *args, **kwargs):
........return self._common(*args, **kwargs)

....def POST(self, *args, **kwargs):
........return self._common(*args, **kwargs)

This is just 4 lines of annoying boilerplate to undo the dispatching
that was 'helpfully' done for you.

I would definitely support a 'request' method (perhaps call it
'dispatch'?) that allows us to avoid that logic.  I suspect that every
view I've created that used a form would be hampered by having dispatch
based on HTTP verb done first.

Luke

--
"Despair: It's always darkest just before it goes pitch black."
(despair.com)

Luke Plant || http://lukeplant.me.uk/


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
David Larlet  
View profile  
 More options Oct 1 2010, 6:42 am
From: David Larlet <lar...@gmail.com>
Date: Fri, 01 Oct 2010 12:42:24 +0200
Local: Fri, Oct 1 2010 6:42 am
Subject: Re: #6735 -- Class based generic views: call for comment

Russell Keith-Magee a crit :

> 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.

Thanks for taking that time.

> I'd like to try and get this in for 1.3. It's a big feature, which
> means it needs to be in by October 18. However, based on the state of
> the patch that Ben has prepared, I think this is an achievable goal.

I think too but it needs a lot of feedback from the community.

> Three things are required to make this happen:

>   * Documentation. It looks like David Larlet has made a start on this
> already, but there's lots more required.

Yes, only a start but I'm working on it, any help is really appreciated.
>   * Conversion of the github project into a patch on trunk.

Do you see that as a total replacement of actual views.generic or should
we go for a old/new dance?
>   * Feedback on the API, especially the generic view replacements.

A first feedback from a fork [1], I think it can be interesting to move
the paginate view too.

> I already have one specific piece of API feedback: the current
> implementation requires that all view logic is contained in GET(),
> POST() etc style views. This is fine, except for the fact that there
> are occasions where GET and POST share a lot of common logic. It would
> make sense to me to allow for a request() method that is the direct
> analog of how we do views right now, wrapping lines 53-59 of base.py
> into a request() method. This would allow users to define their own
> dispatch mechanisms, or share logic between GET and POST (and any
> other http method) as necessary.

What do you think of [2], is that what you have in mind? I chose
dispatch, as Luke suggested, because request can be confusing.

Best,
David

[1]
http://github.com/josesoa/django-class-based-views/commit/5f24e25e83f...
[2]
http://github.com/bfirsh/django-class-based-views/commit/20b63340bbf2...


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
burchik@gmail.com  
View profile  
 More options Oct 1 2010, 6:46 am
From: "burc...@gmail.com" <burc...@gmail.com>
Date: Fri, 1 Oct 2010 17:46:37 +0700
Local: Fri, Oct 1 2010 6:46 am
Subject: Re: #6735 -- Class based generic views: call for comment
Hi Russell,

Few more questions I haven't seen answers yet.

How should urls() work for such views? Should they?
How can self.redirect_to() get current app, namespace and function
name to work if one should use reverse() ?
How should request should be passed for self.render()? Implicitly or explicitly?

You've taken GET/POST dispatch as an example of the new approach, but
I suggest you to use this example (sorry for low-quality draft):

class UserView(View):
    templates_prefix = ''
    users = User.objects.all()
    app_instance = 'users'

    list_template = '%slist.html'
    edit_template = '%sedit.html'

    def template_for(page):
        return getattr(self, 'list_' % self.templates_prefix)

    @property # as we now have >= python 2.4
    def urls(self):
        return patterns('',
            url(r'^$',
                self.list,
                name='%s:list'),
            url(r'^(.+)/$',
                self.edit,
                name='%s:edit'),
        )

    def redirect_to(self, request, page):
        #how to get full path to the page from attribute page???
        return HttpResponseRedirect(request.build_absolute_uri(request)
+ reverse(self, urlconf=request.urlconf) + reverse(page,
urlconf=self.urls))

    def list(self, request):
        return self.render(self.template_for('list'), {'users': self.users})

    def edit(self, request, id):
        if not self.users.filter(id=id).exists():
            return self.redirect_to(self.list)
        return self.render(self.template_for('edit'), {'user':
self.users.get(id=id)})

class CustomersView(View):
    list_template = 'generic_list.html'
    edit_template = 'my_edit.html'
    users = Users.objects.filter(is_staff=False)

url(r'^detail/users/', CustomersView(), name="users", app_name="users"),

On Fri, Oct 1, 2010 at 12:26 PM, Russell Keith-Magee

--
Best regards, Yuri V. Baburov, ICQ# 99934676, Skype: yuri.baburov,
MSN: bu...@live.com

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Andrew Godwin  
View profile  
 More options Oct 1 2010, 7:25 am
From: Andrew Godwin <and...@aeracode.org>
Date: Fri, 01 Oct 2010 12:25:54 +0100
Local: Fri, Oct 1 2010 7:25 am
Subject: Re: #6735 -- Class based generic views: call for comment
On 01/10/10 11:17, Luke Plant wrote:

There's nothing stopping Django shipping a base view which just calls a
request method, and then another base view which inherits from that and
does method-based dispatch - we shouldn't add too many classes, else
it'll be a documentation nightmare, but that seems a sensible split.

Andrew


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ben Firshman  
View profile  
 More options Oct 1 2010, 8:17 am
From: Ben Firshman <b...@firshman.co.uk>
Date: Fri, 1 Oct 2010 13:17:13 +0100
Local: Fri, Oct 1 2010 8:17 am
Subject: Re: #6735 -- Class based generic views: call for comment
I don't think we should worry about documentation nightmares - we could leave most of it undocumented and just expose the bits which look like the current generic views (and a few base views) as the public API.

I have added a "how to help" section to the wiki page:

http://code.djangoproject.com/wiki/ClassBasedViews

Ben

On 1 Oct 2010, at 12:25, Andrew Godwin wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Johannes Dollinger  
View profile  
 More options Oct 1 2010, 6:16 am
From: Johannes Dollinger <emulb...@googlemail.com>
Date: Fri, 1 Oct 2010 12:16:07 +0200
Local: Fri, Oct 1 2010 6:16 am
Subject: Re: #6735 -- Class based generic views: call for comment
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?)

> Based on the discussion on the most recent thread [4], plus in-person
> discussions, I'm proposing that we move forward with Ben Firshman and
> David Larlet's "__call__ + copy()" approach. Yes, the copy() is a bit
> of a weird idiom, but it's not an idiom that users need to be
> particularly concerned with; the code "just works" in an unsurprising
> way.

I disagree. If you define a class-based view, create an instance (a singleton) and put it in your urlconf, you wouldn't (or shouldn't) expect it to magically reinstantiate itself everytime it's called. So at least the docs will have to point out the magic prominently.

Regardless of my resentments, thanks for finally creating an official foundation for class based views.

__
Johannes


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vinay Sajip  
View profile  
 More options Oct 1 2010, 9:53 am
From: Vinay Sajip <vinay_sa...@yahoo.co.uk>
Date: Fri, 1 Oct 2010 06:53:32 -0700 (PDT)
Local: Fri, Oct 1 2010 9:53 am
Subject: Re: #6735 -- Class based generic views: call for comment
On Oct 1, 11:16 am, Johannes Dollinger <emulb...@googlemail.com>
wrote:

> 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?)

I think Johannes has a point. The copy-on-call may seem useful at
first sight, but as it's a shallow copy, it may perhaps engender a
false sense of security. So

view_instance.attr = x

will not result in threads stepping on each other's toes, but

view_instance.container_attr.attr = x

surely will?

It seems better to stress thread-safety dos and don'ts in the
documentation.

Regards,

Vinay Sajip


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Alex Gaynor  
View profile  
 More options Oct 1 2010, 9:55 am
From: Alex Gaynor <alex.gay...@gmail.com>
Date: Fri, 1 Oct 2010 09:55:10 -0400
Local: Fri, Oct 1 2010 9:55 am
Subject: Re: #6735 -- Class based generic views: call for comment

Without wanting to beat a dead horse, I concur.  Fundamentally we need
to have a little faith in your users, the admin has the exact same
pattern of a single instance, and we haven't done anything special
there.

Alex

--
"I disapprove of what you say, but I will defend to the death your
right to say it." -- Voltaire
"The people's good is the highest law." -- Cicero
"Code can always be simpler than you think, but never as simple as you
want" -- Me


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Russell Keith-Magee  
View profile  
 More options Oct 1 2010, 10:43 am
From: Russell Keith-Magee <russ...@keith-magee.com>
Date: Fri, 1 Oct 2010 22:43:38 +0800
Local: Fri, Oct 1 2010 10:43 am
Subject: Re: #6735 -- Class based generic views: call for comment

On Fri, Oct 1, 2010 at 6:46 PM, burc...@gmail.com <burc...@gmail.com> wrote:
> Hi Russell,

> Few more questions I haven't seen answers yet.

> How should urls() work for such views? Should they?

Erm... no. A view doesn't have a collection of URLs. A view is a view.
What we're debating here is a way to construct generic views as a
class, rather than as a method with a hideously long argument list.

This isn't a class based view. It's a collection of views, wrapped in
a class. You might be able to call it an app. #6735 isn't about apps -
it's about single views.

Yours,
Russ Magee %-)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Russell Keith-Magee  
View profile  
 More options Oct 1 2010, 10:58 am
From: Russell Keith-Magee <russ...@keith-magee.com>
Date: Fri, 1 Oct 2010 22:58:40 +0800
Local: Fri, Oct 1 2010 10:58 am
Subject: Re: #6735 -- Class based generic views: call for comment

On Fri, Oct 1, 2010 at 6:42 PM, David Larlet <lar...@gmail.com> wrote:

> Russell Keith-Magee a écrit :

>>  * Conversion of the github project into a patch on trunk.

> Do you see that as a total replacement of actual views.generic or should we
> go for a old/new dance?

Unless you're proposing to maintain backwards compatibility with the
old APIs, we can't just remove the old ones. This essentially means an
old/new arrangement of some kind is required. I'm not especially hung
up on the name, as long as it's simple and memorable.

>>  * Feedback on the API, especially the generic view replacements.

> A first feedback from a fork [1], I think it can be interesting to move the
> paginate view too.

Sounds like an interesting idea.

>> I already have one specific piece of API feedback: the current
>> implementation requires that all view logic is contained in GET(),
>> POST() etc style views. This is fine, except for the fact that there
>> are occasions where GET and POST share a lot of common logic. It would
>> make sense to me to allow for a request() method that is the direct
>> analog of how we do views right now, wrapping lines 53-59 of base.py
>> into a request() method. This would allow users to define their own
>> dispatch mechanisms, or share logic between GET and POST (and any
>> other http method) as necessary.

> What do you think of [2], is that what you have in mind? I chose dispatch,
> as Luke suggested, because request can be confusing.

As I said in my response to Luke -- it's not only confusing; it's
impossible due tot he clash with self.request. Beyond that, it's a bit
of a bikeshed. dispatch(), handle(), or anything else simple and
memorable will be fine.

Yours,
Russ Magee %-)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Russell Keith-Magee  
View profile  
 More options Oct 1 2010, 10:59 am
From: Russell Keith-Magee <russ...@keith-magee.com>
Date: Fri, 1 Oct 2010 22:59:15 +0800
Local: Fri, Oct 1 2010 10:59 am
Subject: Re: #6735 -- Class based generic views: call for comment

It's been pointed out to me that we can't really call it request()
anyway, because it would clash with self.request. dispatch() is as
good a name as any; handle() would be my only other suggestion.
However, this really is bikeshedding at this point. Whoever paints it
gets to pick the name.

Yours,
Russ Magee %-)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tobias McNulty  
View profile  
 More options Oct 1 2010, 11:14 am
From: Tobias McNulty <tob...@caktusgroup.com>
Date: Fri, 1 Oct 2010 11:14:56 -0400
Local: Fri, Oct 1 2010 11:14 am
Subject: Re: #6735 -- Class based generic views: call for comment

On Fri, Oct 1, 2010 at 9:55 AM, Alex Gaynor <alex.gay...@gmail.com> wrote:
> On Fri, Oct 1, 2010 at 9:53 AM, Vinay Sajip <vinay_sa...@yahoo.co.uk>
> wrote:
> > It seems better to stress thread-safety dos and don'ts in the
> > documentation.

> Without wanting to beat a dead horse, I concur.  Fundamentally we need
> to have a little faith in your users, the admin has the exact same
> pattern of a single instance, and we haven't done anything special
> there.

+1

The thread safety issues certainly aren't insignificant, but I think they
can be solved by a big fat warning in the documentation.  I do prefer this
to the potentially false sense of security that copying the object may
involve.

Tobias
--
Tobias McNulty, Managing Partner
Caktus Consulting Group, LLC
http://www.caktusgroup.com


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Russell Keith-Magee  
View profile   Translate to Translated (View Original)
 More options Oct 1 2010, 11:16 am
From: Russell Keith-Magee <russ...@keith-magee.com>
Date: Fri, 1 Oct 2010 23:16:53 +0800
Local: Fri, Oct 1 2010 11:16 am
Subject: Re: #6735 -- Class based generic views: call for comment
On Fri, Oct 1, 2010 at 6:16 PM, Johannes Dollinger

<emulb...@googlemail.com> 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.

The thread-safety argument is more than enough for me.

*If* all requests state was stored on the request, you're correct -
there wouldn't be a need for a class-based view to be instantiated per
request. However, at that point, you're not really using a class --
you're using a collection of methods that share a sub-module
namespace.

> So is this purely about preventing users from shooting themselves in the foot? (hyperbole: Will there be protection from globals in django 1.4?)

"Don't use global variables" is advice that is contained in any
first-year CS textbook.

"Don't use instance variables on a class" isn't advice you're going to
see printed very often. Yet that would be the advice that would be
*required* in order to use stateless class-based views in the way you
describe.

Objects have state. I don't think it's at all unreasonable to suggest
that a instances of a class based view should be able to have state.
And even if we documented the fact that they can't have state, I'm
willing to *guarantee* that people will *try* to make them stateful.

So - we can:
 * spend a bunch of time writing infrastructure to prevent people from
putting stateful variables onto their class-based views
 * spend a bunch of time answering the same question over and over
again on django-users
 * pick an infrastructure that lets people use classes the way they expect.

>> Based on the discussion on the most recent thread [4], plus in-person
>> discussions, I'm proposing that we move forward with Ben Firshman and
>> David Larlet's "__call__ + copy()" approach. Yes, the copy() is a bit
>> of a weird idiom, but it's not an idiom that users need to be
>> particularly concerned with; the code "just works" in an unsurprising
>> way.

> I disagree. If you define a class-based view, create an instance (a singleton) and put it in your urlconf, you wouldn't (or shouldn't) expect it to magically reinstantiate itself everytime it's called. So at least the docs will have to point out the magic prominently.

You say "magic", I say an unusual, but otherwise elegant solution for
hiding an annoying implementation detail.

As an end user, you don't have to care about the fact that it's
"magically" instantiated every time it is used. It just behaves like a
class instance, and is thread safe without you having to think about
it.

Yours,
Russ Magee %-)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Alex Gaynor  
View profile  
 More options Oct 1 2010, 11:20 am
From: Alex Gaynor <alex.gay...@gmail.com>
Date: Fri, 1 Oct 2010 11:20:26 -0400
Local: Fri, Oct 1 2010 11:20 am
Subject: Re: #6735 -- Class based generic views: call for comment
On Fri, Oct 1, 2010 at 11:16 AM, Russell Keith-Magee

Not really.  The big win from a class-based view is not being able to
store state, you can do that with local variables, it's being able to
override parts of the behavior without needing to rewrite the entire
view, or add 101 parameters.

We don't have that documentation for the admin.  Either we need it, or
our users are a little bit smarter than we're giving them credit.

Alex

--
"I disapprove of what you say, but I will defend to the death your
right to say it." -- Voltaire
"The people's good is the highest law." -- Cicero
"Code can always be simpler than you think, but never as simple as you
want" -- Me


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Brandon Konkle  
View profile  
 More options Oct 1 2010, 11:25 am
From: Brandon Konkle <brandon.kon...@gmail.com>
Date: Fri, 1 Oct 2010 10:25:33 -0500
Local: Fri, Oct 1 2010 11:25 am
Subject: Re: #6735 -- Class based generic views: call for comment
On Oct 1, 2010, at 10:20 AM, Alex Gaynor wrote:

> Not really.  The big win from a class-based view is not being able to
> store state, you can do that with local variables, it's being able to
> override parts of the behavior without needing to rewrite the entire
> view, or add 101 parameters.

If you're storing state with local variables, though, don't you end up having to pass 101 parameters around to your methods?

-Brandon


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Russell Keith-Magee  
View profile  
 More options Oct 1 2010, 11:37 am
From: Russell Keith-Magee <russ...@keith-magee.com>
Date: Fri, 1 Oct 2010 23:37:14 +0800
Local: Fri, Oct 1 2010 11:37 am
Subject: Re: #6735 -- Class based generic views: call for comment

I'm in agreement that this is the gain from class-based views.
However, as soon as you show someone an instance of a class, they're
going to look for the instance attributes -- that's just how classes
work everywhere else in the world.

Unless you can propose a mechanism for physically preventing people
from assigning instance attributes to the class, I simply don't buy
that documentation saying "don't do that" will be sufficient to avoid
confusion.

Or a third option -- the use case for the admin is different.
ModelAdmin is a pret-a-porter interface to a high level piece of
functionality with a couple of clearly documented extension points.
The API that ModelAdmin exposes doesn't provide any encouragement to
store state on the ModelAdmin instance itself. The fact that
ModelAdmin isn't thread safe in that way isn't documented, because
it's simply never been an issue -- the interface it provides doesn't
encourage you to do things that would cause the thread non-safety to
be exposed.

This contrasts directly with Class-based views: a low-level view
construction kit. Although the interface for the generic class-based
views will be well defined in the same way as the admin, the base View
class isn't. Best practice may well be to avoid state variables, but I
don't think any amount of documentation will stop people from using
them.

Yours,
Russ Magee %-)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Andrew Godwin  
View profile  
 More options Oct 1 2010, 11:38 am
From: Andrew Godwin <and...@aeracode.org>
Date: Fri, 01 Oct 2010 16:38:34 +0100
Local: Fri, Oct 1 2010 11:38 am
Subject: Re: #6735 -- Class based generic views: call for comment
On 01/10/10 16:25, Brandon Konkle wrote:

> On Oct 1, 2010, at 10:20 AM, Alex Gaynor wrote:

>> Not really.  The big win from a class-based view is not being able to
>> store state, you can do that with local variables, it's being able to
>> override parts of the behavior without needing to rewrite the entire
>> view, or add 101 parameters.

> If you're storing state with local variables, though, don't you end up having to pass 101 parameters around to your methods?

> -Brandon

This is a very good point - one of the reasons it's nice to have
self.request is so you don't end up with ridiculous method signatures.
It's also a lot easier to write inflexible methods if you don't have
state on self - if I'm in, say, get_form(), and I want to change the
form I have based on the arguments in the URL (or anything elsewhere in
the class), I can't do that unless someone thought to pass those
variables in initially in the method signature.

Andrew


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Luke Plant  
View profile  
 More options Oct 1 2010, 12:07 pm
From: Luke Plant <L.Plant...@cantab.net>
Date: Fri, 01 Oct 2010 17:07:15 +0100
Local: Fri, Oct 1 2010 12:07 pm
Subject: Re: #6735 -- Class based generic views: call for comment

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?

Luke

--
"Despair: It's always darkest just before it goes pitch black."
(despair.com)

Luke Plant || http://lukeplant.me.uk/


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Santiago Perez  
View profile  
 More options Oct 1 2010, 12:17 pm
From: Santiago Perez <san...@santip.com.ar>
Date: Fri, 1 Oct 2010 13:17:19 -0300
Local: Fri, Oct 1 2010 12:17 pm
Subject: Re: #6735 -- Class based generic views: call for comment

> 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?

I'm not very convinced about this but I'll just throw it out there, how
about keeping the same state object in each request instance (assigned at
the base __call__ implementation) and overriding getattr and setattr to work
with the state object in request (getattr would fallback to regular
attributes set during the constructor when no request was present)? Although
this would require using threadlocals to access the right request object
from getattr and setattr.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Luke Plant  
View profile   Translate to Translated (View Original)
 More options Oct 1 2010, 12:31 pm
From: Luke Plant <L.Plant...@cantab.net>
Date: Fri, 01 Oct 2010 17:31:59 +0100
Local: Fri, Oct 1 2010 12:31 pm
Subject: Re: #6735 -- Class based generic views: call for comment
Or, more drastically, we could just do this:

class View(object):
    def __call__(self, request, *args, **kwargs):
        self.request = request
        self.args = args
        self.kwargs = kwargs
        resp = self.dispatch(request, *args, **kwargs)
        self.__dict__ = {} # goodbye state!
        return resp

This would kill the ability to use __init__ to store anything on the
instance, since it would only work for the first request, and so would
enforce subclassing as the only means of customising behaviour. It would
be more effective at dealing with thread safety concerns than a
'copy()', but breaking __init__() like that is fairly evil. I'm not sure
if this is a serious suggestion or not...

Luke

--
"Despair: It's always darkest just before it goes pitch black."
(despair.com)

Luke Plant || http://lukeplant.me.uk/


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Santiago Perez  
View profile  
 More options Oct 1 2010, 1:25 pm
From: Santiago Perez <san...@santip.com.ar>
Date: Fri, 1 Oct 2010 14:25:30 -0300
Local: Fri, Oct 1 2010 1:25 pm
Subject: Re: #6735 -- Class based generic views: call for comment

> This would kill the ability to use __init__ to store anything on the
> instance, since it would only work for the first request, and so would
> enforce subclassing as the only means of customising behaviour. It would
> be more effective at dealing with thread safety concerns than a
> 'copy()', but breaking __init__() like that is fairly evil. I'm not sure
> if this is a serious suggestion or not...

if you remove the ability to set state in the constructor and rely
only in subclassing use __new__ instead of copy and all the thread
safety problems are solved.

Perhaps we could do something like that and provide a @classmethod in
View that easily subclasses a View with some default state, for
example:

views.py
------------
MyView(View):
    ...
urls.py
----------
url(r'^myview$', myapp.views.MyView, name='myview'),
url(r'^myview$', myapp.views.MyView.with_defaults(somevar=somevalue),
name='myview'),


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Johannes Dollinger  
View profile  
 More options Oct 1 2010, 1:44 pm
From: Johannes Dollinger <emulb...@googlemail.com>
Date: Fri, 1 Oct 2010 19:44:19 +0200
Local: Fri, Oct 1 2010 1:44 pm
Subject: Re: #6735 -- Class based generic views: call for comment

Am 01.10.2010 um 18:07 schrieb Luke Plant:

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 must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Messages 1 - 25 of 103   Newer >
« Back to Discussions « Newer topic     Older topic »