#6375 -- Class Based Views: Opinions on commit plan

22 views
Skip to first unread message

Russell Keith-Magee

unread,
Oct 14, 2010, 12:19:13 PM10/14/10
to Django Developers
Hi all,

With the deadline for 1.3 alpha rapidly approaching, it's getting to
crunch time for class-based views.

The wiki page [1] now contains a good summary of the debate so far,
showing why we have ended up at the "ClassBasedView.as_view()"
deployment solution. I've also got a implementation up on my bitbucket
repo [2] (in the class-based-views branch) that is integrated into the
Django source tree.

I've done an audit of the simple (template and redirect), detail and
list views, and I'm reasonably happy with the feature set, feature
parity with old-style function views, and test coverage. I've also
checked that the outstanding generic-view tickets (#1282, #2367,
#8378, #9150, #12669, #13753, and #13953) are solved or are solvable
using the new class-based framework.

The following things are still needed:

* An audit of create/update views.
* An audit of date views.
* Documentation, including
- changes to the tutorial
- topic documentation
- reference documentation
- a migration guide for function generic views to class-based generic views
* Feedback from the community on the API that has been exposed.
* Fixing Django's handling of PUT requests (this currently raises an
expected failure in the test suite)

Unfortunately, the 1.3 alpha deadline is Monday. Over the next couple
of days, I intend to finish my audit of edit and date views, and make
a start on at least reference documentation, but it's highly unlikely
I'm going to get all the items on this list done by Monday.

So - I'd like to field opinions on committing class-based views in an
'almost finished' state.

I won't commit anything until at least my review of create/update and
date views is complete. In particular, I'm not especially happy with
the current state of the create/update views. I'd also like to see a
couple of independent reviews of the API as a sanity check.

Then, during the beta period, we will need to expand on the
documentation and finish the other outstanding items. I would also
expect to see some minor tweaks to the API as different use cases
emerge. Some of these changes may be backwards incompatible, but I
don't anticipate any widespread changes being necessary. Once we hit
beta, I would anticipate that any backwards incompatible changes we
need to make will have shaken out.

One piece of evidence supporting this plan: history has shown us that
we don't really get much serious testing of new features until they
hit trunk, and we don't get the *really* serious testing until a final
release is made. Getting an 'almost finished' version into trunk may
actually help the feature develop faster than it would if we postponed
to 1.4, hoping that it will mature in a separate branch.

Any opinions or objections to this plan?

[1] http://code.djangoproject.com/wiki/ClassBasedViews
[2] http://bitbucket.org/freakboy3742/django - (class-based-views branch)

Yours,
Russ Magee %-)

Justin Lilly

unread,
Oct 14, 2010, 1:09:31 PM10/14/10
to django-d...@googlegroups.com
Because you asked, I think this sounds like a great idea.

When you have decided you like the API for create/update
views, please send another email to the list, so that we
know we've hit a stable API to write documentation
against.

-justin

Łukasz Rekucki

unread,
Oct 14, 2010, 4:43:27 PM10/14/10
to django-d...@googlegroups.com
On 14 October 2010 18:19, Russell Keith-Magee <rus...@keith-magee.com> wrote:
>
> The following things are still needed:
>
>  * An audit of create/update views.
>  * An audit of date views.

I was planning on hacking onto this on today/tomorrow. Also see below.

>  * Documentation, including
>    - changes to the tutorial
>    - topic documentation
>    - reference documentation
>    - a migration guide for function generic views to class-based generic views

That's probably not something I can help with much :( - no really, I'm
terrible at documenting things (and even worse in doing it in foreign
language).

>  * Feedback from the community on the API that has been exposed.

This is a kind of "what came first" dilema. As you already mentioned,
most APIs don't get lots of testing and feedback until they are
released. There is this crazy idea im my mind to mark CBVs API as
"Beta" in 1.3 and put a big warning in the docs that it can change in
backwards-incompatible was in 1.4. A precedence to this would be
`databrowse`[1], but we could actually finish it this time ;).

Anyway, here are my thoughts that troubled me this week[2].

>  * Fixing Django's handling of PUT requests (this currently raises an
> expected failure in the test suite)

Any hints on this, anyone ? Is this as trivial as putting the
`corce_post_put()` in the BaseHandler.

>
> Unfortunately, the 1.3 alpha deadline is Monday. Over the next couple
> of days, I intend to finish my audit of edit and date views, and make
> a start on at least reference documentation, but it's highly unlikely
> I'm going to get all the items on this list done by Monday.
>
> So - I'd like to field opinions on committing class-based views in an
> 'almost finished' state.

+1. This feature is too important to drop it once again.

[1]: http://docs.djangoproject.com/en/dev/ref/contrib/databrowse/
[2]: http://gist.github.com/627001

Russell Keith-Magee

unread,
Oct 15, 2010, 1:06:10 AM10/15/10
to django-d...@googlegroups.com
2010/10/15 Łukasz Rekucki <lrek...@gmail.com>:

> On 14 October 2010 18:19, Russell Keith-Magee <rus...@keith-magee.com> wrote:
>>
>> The following things are still needed:
>>
>>  * An audit of create/update views.
>>  * An audit of date views.
>
> I was planning on hacking onto this on today/tomorrow. Also see below.
>
>>  * Documentation, including
>>    - changes to the tutorial
>>    - topic documentation
>>    - reference documentation
>>    - a migration guide for function generic views to class-based generic views
>
> That's probably not something I can help with much :( - no really, I'm
> terrible at documenting things (and even worse in doing it in foreign
> language).

Don't discount your skills here. Your english is at least as good as
some native speakers I know (plus, your English is a lot better than
my Polish :-)

Plus -- the hardest bit of writing documentation is almost always the
first draft. That bit requires you to work out a good organization of
your ideas, get examples worked out, and so on. Once you've got a
first draft, polishing the language is relatively easy.

If members of the community can provide good first drafts, I'm happy
to carry the text the rest of the way -- even if the draft has
occasionally slightly stilted english because of a non-native speaker.
Fixing quirks of grammar is easy. Coming up with good ideas isn't.

>>  * Feedback from the community on the API that has been exposed.
>
> This is a kind of "what came first" dilema. As you already mentioned,
> most APIs don't get lots of testing and feedback until they are
> released.

For sure. At this point, I'm trying to just trying entice the
adventurous souls out of hiding to take a look. I'm just looking for
*some* feedback that indicates that what is on the table isn't
completely off base.

> There is this crazy idea im my mind to mark CBVs API as
> "Beta" in 1.3 and put a big warning in the docs that it can change in
> backwards-incompatible was in 1.4. A precedence to this would be
> `databrowse`[1], but we could actually finish it this time ;).

That thought has occurred to me in the past. My concern is how we
manage such an idea as a project. Backwards compatibility is a big
deal, and one of Django's big selling points IMHO.

So - the question becomes how can we introduce a new feature, but give
people fair warning that they're using a feature that is subject to
change? Python's 'from __future__' is a really good approach to this,
IMHO -- i.e., an explicit opt-in to new features. There might be some
room to explore this sort of idea for Django.

However, this isn't a decision we need to make right now. If we land
what we have, we can fiddle with it until the RC comes out; if we are
getting to that point and we're making API changes, we can look at our
options for providing adequate warnings.

> Anyway, here are my thoughts that troubled me this week[2].

Thanks for that feedback.

Regarding mixins:

I agree about the ProcessFormView and DisplayFormView differences;
that's one of the issues I'm struggling with in the edit views.

The issue of a JSON view overriding a TemplateMixin is a valid one;
the easy solution here is to include a "BaseUpdateView", and then make
"UpdateView" do nothing but include the TemplateMixin. My concern here
is the proliferation of base classes that don't really contribute
anything but make the class hierarchy that much harder to explain.

I'm uncertain myself about the best way to handle error processing. As
you noted, having methods that raise NotImplemented is problematic,
because they then place constraints on MRO ordering. Using ABCs would
be a nice touch, but it's not one available to us since we need
support for Python 2.4.

Given that we're shipping a bunch of known views that won't be subject
to these problems, and any collection of mixins that is missing a
required method will raise 'no such method' errors fairly early in the
process, I'm inclined to say that we should just leave out this kind
of error handling. The last option you mention -- empty methods --
mean the 'no such method' error is replaced by a range of errors
depending on how the return value from the method is used. If a mixin
can't provide a sensible default implementation, I'd rather see a
consistent 'no such method' error.

The issue of teaching MRO doesn't especially worry me, because we
don't really have to teach the full MRO. Our inheritance hierarchies
will be shallow and wide, not deep and convoluted; for almost all
practical purposes, MRO is explained as "first implementation in the
mixin list wins". Sure, there will be some exceptions, but most of the
interesting edge cases of MRO (e.g., diamond inheritance patterns)
aren't cases that most users will encounter.

Regarding get_* methods:

I share many of your concerns about the way we're using get methods.

In the current implementation, there's a good reason for them to *not*
be properties -- the need to take arguments.

However, this could be a symptom of a larger problem. For example, the
fact that get_object() changes signature depending on how and when it
is called is somewhat concerning to me. It's harder to explain (since
you need to be aware of when certain arguments are required) but it
also makes things harder to use -- since you can't just generically
call get_object(), you need to know what extra magic it expects.

One possibility is to rely on view state a lot more -- make
get_object() a property, and then make implementations check self for
the extra values they need to work. However, I'm not sure how
comfortable I am with making such strong use of globals like this.

I'm certainly open to suggestions here. One of the reasons I haven't
finished my audit of the edit and date views is that I'm not entirely
happy with the answers I've arrived at with regards to questions like
the one you raise about get_* methods.

Lastly, regarding response classes:

It sounds like the problem you're describing is that calls to "return
HttpResponse()" need to be abstracted behind functions that allow you
to return your own custom response types. I don't have any objection
to this in principle.

>>  * Fixing Django's handling of PUT requests (this currently raises an
>> expected failure in the test suite)
>
> Any hints on this, anyone ? Is this as trivial as putting the
> `corce_post_put()` in the BaseHandler.

This will work, but I'd like to put a little more thought into the
"right" solution. Forcing PUT data into POST seems like something that
could have unexpected consequences long term. There's also the related
issue of handling non-form-encoded data properly; raw_post_data is
also a bit of a hack at present. Again, suggestions (and volunteers)
welcome.

Yours,
Russ Magee %-)

Yo-Yo Ma

unread,
Oct 15, 2010, 1:59:01 AM10/15/10
to Django developers
I realize this is a bit late and not even the "right" discussion, bit
I just stumbled across this and the wiki, and I feel a bit sick to my
stomach.

1) self.request?

Whatever gains come from this will be offset by loss in design. A
method is called by a request. That is simple common sense. A method
doesn't access a request. I'm sorry, if I'm missing something here,
but this seems as backward as an intentional sabotage to Django would
be.

2) "getting in the way if you do want to share a lot of code between
GET and POST methods"

For those of us not reinventing the blog, or creating content sites,
this is an automatic disadvantage.

3) .as_view()?

Nothing needs to be said about the confusing mess that is the class
based views API.

4)
>> "There are quite a few sets of class-based views out there" == Jusification
False

Russell Keith-Magee

unread,
Oct 15, 2010, 2:11:54 AM10/15/10
to django-d...@googlegroups.com
On Fri, Oct 15, 2010 at 1:59 PM, Yo-Yo Ma <baxters...@gmail.com> wrote:
> I realize this is a bit late and not even the "right" discussion, bit
> I just stumbled across this and the wiki, and I feel a bit sick to my
> stomach.
>
> 1) self.request?
>
> Whatever gains come from this will be offset by loss in design. A
> method is called by a request. That is simple common sense. A method
> doesn't access a request. I'm sorry, if I'm missing something here,
> but this seems as backward as an intentional sabotage to Django would
> be.
>
> 2) "getting in the way if you do want to share a lot of code between
> GET and POST methods"
>
> For those of us not reinventing the blog, or creating content sites,
> this is an automatic disadvantage.
>
> 3) .as_view()?
>
> Nothing needs to be said about the confusing mess that is the class
> based views API.

In fact, a great deal *has* been said. The most recent mailing list
thread about this exact topic ran to *over 100 messages*. That's the
second mailing list thread in recent memory that ran to comparable
length, and the topic has been discussed many times over the years.

as_view() exists for a very good reason. The same goes for
self.request, and the dispatch mechanism.

It seems to me that before you weigh into a discussion that you've
"just stumbled into", and you're concerned by what you see, you might
want to avail yourself of the opportunity reading the history that has
led us to the design that we have on the table. We're not stupid, and
the designs that exist, exist for a reason.

We're happy to entertain design suggestions, but only if they're
enlightened by the extensive discussions that have proceeded the
implementation that we have. You're free to say "as_view() sucks", but
unless you are proposing an *specific* alternative that isn't fraught
with the problems that led us to that solution in the first place,
you're not going to get much traction.

Yours,
Russ Magee %-)

Sebastian Pawlus

unread,
Oct 15, 2010, 4:01:45 AM10/15/10
to django-d...@googlegroups.com
Maybe not important but makes bit harder to find in it trac :)
Russ there is a typo in subject, ticket id is #6735, not 6375.

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

David De La Harpe Golden

unread,
Oct 15, 2010, 8:30:22 AM10/15/10
to django-d...@googlegroups.com
On 15/10/10 07:11, Russell Keith-Magee wrote:

> We're happy to entertain design suggestions, but only if they're
> enlightened by the extensive discussions that have proceeded the
> implementation that we have. You're free to say "as_view() sucks", but
> unless you are proposing an *specific* alternative that isn't fraught
> with the problems that led us to that solution in the first place,
> you're not going to get much traction.
>

I find the use of an .as_view() direct classmethod vaguely peculiar
given classmethods have been avoided elsewhere in django in favor of the
flexible "Manager" pattern?

Why not have views class property on the class by analogy with the
"objects" property, that the resolver calls a "get" method on with the
params to get a view instance?

class BlahViewDirector(Director): # director:view::manager:model
...

class Blah(View):
views = BlahDirector() # or left out for a "default director"
...


url(r'blah/(?P<key>\d+)/$'), views.Blah, name="blah")
url(r'blah/(?P<key>\d+)/glonk/$'), views.Blah, glonk=True)

=>
Blah.views.get(key=key) and
Blah.views.get(key=key, glonk=True) to get a Blah instance
that's perhaps itself a callable expecting a request, or has
GET/POST/PUT etc. methods.

Wouldn't that be rather more in keeping with the structure of the rest
of the framework? A Director could be simple or sophisticated
(e.g. caching and reusing instances thread-safely), much like a Manager.


Russell Keith-Magee

unread,
Oct 15, 2010, 8:49:27 AM10/15/10
to django-d...@googlegroups.com
On Fri, Oct 15, 2010 at 8:30 PM, David De La Harpe Golden
<david.delah...@ichec.ie> wrote:
> On 15/10/10 07:11, Russell Keith-Magee wrote:
>
>> We're happy to entertain design suggestions, but only if they're
>> enlightened by the extensive discussions that have proceeded the
>> implementation that we have. You're free to say "as_view() sucks", but
>> unless you are proposing an *specific* alternative that isn't fraught
>> with the problems that led us to that solution in the first place,
>> you're not going to get much traction.
>>
>
> I find the use of an .as_view() direct classmethod vaguely peculiar
> given classmethods have been avoided elsewhere in django in favor of the
> flexible "Manager" pattern?
>
> Why not have views class property on the class by analogy with the
> "objects" property, that the resolver calls a "get" method on with the
> params to get a view instance?

Why not? Because of decoration. If the URL resolver needs to
manipulate the thing that is defined in a URL pattern, that means you
can't use decorators in the URL pattern. See the wiki for more details
[1].

To try and head this off at the pass: when I said any feedback is
welcome, I was really referring to the organization of the class-based
views themselves, not the dispatch mechanism. There's been a *lot* of
thought put into the dispatch mechanism -- read the archives if you
don't believe me -- and we've come to the conclusion that as_view() is
the best of a less-than-ideal set of solutions.

If you *really* think you've discovered the perfect solution that
nobody else has proposed:

1) No, really, you haven't. Check the wiki archives, and I'll give
good odds that *someone* has proposed your idea before, and the
problems that exist with the idea have been explored.

2) If your specific idea hasn't been suggested, it can probably be
ruled out for one of the clearly documented reasons in the wiki, so
you'd better be *really* certain that it addresses the issues that are
described in the wiki.

3) You'd better come armed with a demonstration implementation that,
at the very least, meets all the use cases described by Luke Plant's
experimentation suite [2].

I'm sorry if this seems rude or curt, but the last thing we need at
this point is another round of attempted bikeshedding on dispatch
mechanisms. This isn't a trivial problem. A lot of thought has gone
into the solution that is on the table. If you're going to enter the
discussion at this late stage, the very least you can do is give the
rest of the community the courtesy of coming up to speed with the
debate so we don't have to rehash old ground yet again.

[1] http://code.djangoproject.com/wiki/ClassBasedViews
[2] http://bitbucket.org/spookylukey/django-class-views-experiments/src/tip/

Yours,
Russ Magee %-)

Luke Plant

unread,
Oct 15, 2010, 9:20:07 AM10/15/10
to django-d...@googlegroups.com
On Fri, 2010-10-15 at 00:19 +0800, Russell Keith-Magee wrote:

> Unfortunately, the 1.3 alpha deadline is Monday. Over the next couple
> of days, I intend to finish my audit of edit and date views, and make
> a start on at least reference documentation, but it's highly unlikely
> I'm going to get all the items on this list done by Monday.
>
> So - I'd like to field opinions on committing class-based views in an
> 'almost finished' state.

I'm happy with your proposed plan. I agree that some of the details will
only solidify once people start to use it, and that these can be
considered as bug fixes to the essential feature. I'm afraid I won't be
able to help with reviewing anything over this weekend.

Regards,

Luke

--
"I asked mom if I was a gifted child. She said they certainly
wouldn't have paid for me." (Calvin and Hobbes)

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

Ian Lewis

unread,
Oct 15, 2010, 9:52:08 AM10/15/10
to django-d...@googlegroups.com
On Fri, Oct 15, 2010 at 2:06 PM, Russell Keith-Magee <rus...@keith-magee.com> wrote:

> There is this crazy idea im my mind to mark CBVs API as
> "Beta" in 1.3 and put a big warning in the docs that it can change in
> backwards-incompatible was in 1.4. A precedence to this would be
> `databrowse`[1], but we could actually finish it this time ;).

That thought has occurred to me in the past. My concern is how we
manage such an idea as a project. Backwards compatibility is a big
deal, and one of Django's big selling points IMHO.

So - the question becomes how can we introduce a new feature, but give
people fair warning that they're using a feature that is subject to
change? Python's 'from __future__' is a really good approach to this,
IMHO -- i.e., an explicit opt-in to new features. There might be some
room to explore this sort of idea for Django.

However, this isn't a decision we need to make right now. If we land
what we have, we can fiddle with it until the RC comes out; if we are
getting to that point and we're making API changes, we can look at our
options for providing adequate warnings.

I'm with Russ here. I'd be wary of introducing exceptions to the current backwards-compat policy. It's relatively simple, many people are familiar with it, and I don't think it should change in surprising ways. The 'from __future__' idea is compelling and I like it but I would avoid introducing half baked features in a Django release. I expect most people like frameworks to "work".

Andrew Godwin

unread,
Oct 15, 2010, 10:26:23 AM10/15/10
to django-d...@googlegroups.com
Me too; if it's half-baked, people are still going to get annoyed when we start changing it, and otherwise aren't going to use/test it properly. It's not like we're getting rid of the old function-based generic views, either.

It's well known that people don't really test stuff properly till it lands in trunk, and I think it's a mature enough implementation that we're better off landing it and getting feedback than putting it in a special corner and bikeshedding a bit more. I'd rather get feedback from the userbase at large, which I think is where we'll really learn what needs changing, if anything.

Andrew

Russell Keith-Magee

unread,
Oct 15, 2010, 12:45:42 PM10/15/10
to django-d...@googlegroups.com

I've finished my review of the create/update and date views. I've also
tweaked aspects of the base, detail and list views following feedback
and suggestions from IRC.

I've also added the placeholder skeleton of some documentation:
* a reference guide
* a topic guide, and
* a migration guide

So - review and document away :-)

Yours,
Russ Magee %-)

Yo-Yo Ma

unread,
Oct 15, 2010, 3:40:30 PM10/15/10
to Django developers
My strong suggestion (again prima facie to this discussion) is:

Do not include something as controversial into the trunk, especially
with the justification of, "There are quite a few sets of class-based
views out there". If the API for this feature was not so intrinsically
obscure, it might be a more obvious choice to include it right away,
but considering the "don't break the API" locked in nature of Django's
trunk, it might be worth rehashing this argument after 1.3. Almost
making it into the trunk will have surely opened a lot of eyes and
will undoubtedly bring about new Git Hub forks with possibly better
implementations and alternative APIs for class-based views. Something
much better will come and it'll be too late.

,
On Oct 15, 12:11 am, Russell Keith-Magee <russ...@keith-magee.com>
wrote:

Łukasz Rekucki

unread,
Oct 15, 2010, 4:10:21 PM10/15/10
to django-d...@googlegroups.com
On 15 October 2010 21:40, Yo-Yo Ma <baxters...@gmail.com> wrote:
> My strong suggestion (again prima facie to this discussion) is:
>
> Do not include something as controversial into the trunk, especially
> with the justification of, "There are quite a few sets of class-based
> views out there".

That section probably needs extending, but imho it didn't get much
love, because we pretty much all agree we need this feature for
reusable apps to make sense. The only question is how to do it and
this was discussed many times in the passed, discussed on
DjangoCon[1][2] and recently on this mailing list for over a week with
over 100 posts. So, no - that's not the only justification.

> If the API for this feature was not so intrinsically
> obscure, it might be a more obvious choice to include it right away,

This isn't very constructive. If you want to show us a better API,
just fork Rusell's code[3] and go ahead.

> but considering the "don't break the API" locked in nature of Django's
> trunk, it might be worth rehashing this argument after 1.3. Almost
> making it into the trunk will have surely opened a lot of eyes and
> will undoubtedly bring about new Git Hub forks with possibly better
> implementations and alternative APIs for class-based views. Something
> much better will come and it'll be too late.

So we should because there might be a better solution in next 6 months
? I don't think that is how "perfectionists with deadlines" work. This
is something that has been considered for over 2 years now. Perfection
is good, but the deadline is almost here, IMHO.

So if you really are concerned with state of CBV, come help out! Just
shouting "your API sucks" doesn't help anyone.

[1]: http://blip.tv/file/4109272
[2]: http://blip.tv/file/4108781
[3]: http://bitbucket.org/freakboy3742/django

--
Łukasz Rekucki

Yo-Yo Ma

unread,
Oct 16, 2010, 12:31:41 AM10/16/10
to Django developers
Łukasz Rekucki,

Thanks for the reply. I wasn't being cynical when I said:

> If the API for this feature was not so intrinsically
> obscure, it might be a more obvious choice to include it right away,

What I meant was the design and implementation creates an unusable API
by default. This is a sign that it's not quite ready. I don't suggest
putting it off for another 2 years, but now that things are really
starting to roll with Django, and more developers are getting added,
it's worst time to start shoveling things in that a lot of people
don't like, crippling production and evolution that could otherwise
come very quickly now.

> come help out!

What do you call this. I don't see how any software developer could
consider constructive criticism as anything other than helping out.
Just about 90% of software development is in the mind (at least for
me), and the other 10% is spent typing as fast as I can.



On Oct 15, 2:10 pm, Łukasz Rekucki <lreku...@gmail.com> wrote:

Ian Lewis

unread,
Oct 16, 2010, 1:56:08 AM10/16/10
to django-d...@googlegroups.com
On Sat, Oct 16, 2010 at 1:31 PM, Yo-Yo Ma <baxters...@gmail.com> wrote:
Łukasz Rekucki,

Thanks for the reply. I wasn't being cynical when I said:

> If the API for this feature was not so intrinsically
> obscure, it might be a more obvious choice to include it right away,

What I meant was the design and implementation creates an unusable API
by default. This is a sign that it's not quite ready. I don't suggest
putting it off for another 2 years, but now that things are really
starting to roll with Django, and more developers are getting added,
it's worst time to start shoveling things in that a lot of people
don't like, crippling production and evolution that could otherwise
come very quickly now.

> come help out!

What do you call this. I don't see how any software developer could
consider constructive criticism as anything other than helping out.
Just about 90% of software development is in the mind (at least for
me), and the other 10% is spent typing as fast as I can.

Are you arguing that the API is bad or are you arguing that features where the API could change shouldn't land in trunk? If you are arguing for the former then I think you'll need to be a lot more concrete about what you don't like and how to fix it to really get traction at this point. If it's the later then I can see the point, I know I have tracked trunk in the past when developing projects (I know it's not a great idea), but I think the merits of getting things tested properly outweighs the demerits in this case so it's worth trying out. I wouldn't think the API will change much anyway.

--
Ian

http://www.ianlewis.org/

Gabriel Hurley

unread,
Oct 16, 2010, 3:34:41 AM10/16/10
to Django developers
> What do you call this. I don't see how any software developer could
> consider constructive criticism as anything other than helping out.

You've posted three messages in this thread, but none of them seem
"constructive" to me. You've pointed out areas of disagreement and
used inflammatory hyperbole, but not offered your alternatives or
improvements.

While I firmly stand by your right to disagree with this API and
anything else you see fit (including this response), this API
represents consensus. It is the result of months (maybe years) of
work, hundreds of messages between tens of developers, dozens of
discussions, numerous attempts at different implementations, and who
knows how many man-hours spent on it... In fact, it may be the most
thoroughly discussed feature I've seen in my time with Django.

So the question stands, what would your implementation look like? How
would it improve things and still avoid all the pitfalls that have
been mentioned over the course of development?

Respectfully,

- Gabriel

Brian Neal

unread,
Oct 16, 2010, 2:15:10 PM10/16/10
to Django developers
On Oct 16, 2:34 am, Gabriel Hurley <gab...@gmail.com> wrote:
> > What do you call this. I don't see how any software developer could
> > consider constructive criticism as anything other than helping out.
>
> You've posted three messages in this thread, but none of them seem
> "constructive" to me. You've pointed out areas of disagreement and
> used inflammatory hyperbole, but not offered your alternatives or
> improvements.

Yes. There is nothing constructive here. All you have done is made
digs at what is on the table using unnecessarily provocative language
without making any kind of suggestion about how to improve it. Go back
and read what you wrote ("sick to my stomach", "confusing mess",
"intentional sabotage"), all without elaborating on why you feel this
way, nor offering concrete suggestions for improving it. You are being
the opposite of constructive. You are just throwing rocks.

Yo-Yo Ma

unread,
Oct 16, 2010, 4:24:02 PM10/16/10
to Django developers
Gabriel

You don't have to go to thesaurus.com with the intention of generating
a more formidable argument. I was merely offering my opinion. Playing
devil's advocate should be regarded as counter constructive. If I see
a man about to throw an egg at an otherwise clean wall, I don't need
to offer him an alternative weapon in order to tell him it's not a
good idea to throw eggs at clean walls. I take a more hueristic
approach to my suggestions. If something is obviously not 100% ideal,
will obviously lead to problems in the near future, and doesn't need
to be done right away (view functions work fine), why do it? Why not
wait until something that is obviously correct comes about? As the
wiki states, there are many implementations out there. With many more
something really right will come. Complaining about a passer by with
an opinion and suggesting that they "help" by writing code is much
like asking a guy who shouts, "Your back tire is flat." to fix your
tire or go away. Take advice or leave it. Don't complain when you get
it.

Yo-Yo Ma

unread,
Oct 16, 2010, 4:39:23 PM10/16/10
to Django developers
Typo (on iPhone): should read, "...devil's advocate shouldn't be..."

Michael

unread,
Oct 16, 2010, 5:00:50 PM10/16/10
to django-d...@googlegroups.com
> I was merely offering my opinion. Playing
> devil's advocate should[n't] be regarded as counter constructive.

But it is, playing devil's advocate is by definition a destructive
position. There's nothing particularly wrong with that in general, but
it's a little late in the class-based-views discussion to be starting.

> If something is obviously not 100% ideal,
> will obviously lead to problems in the near future, and doesn't need
> to be done right away (view functions work fine), why do it?

Because that's the only way things every get done. Nothing is ever 100%
ideal or without consequences. It's advance or stagnate, and the
consensus seems to be to advance.

> Complaining about a passer by with
> an opinion and suggesting that they "help" by writing code is much
> like asking a guy who shouts, "Your back tire is flat." to fix your
> tire or go away.

Only they already know the tire is flat. They've already pulled over,
taken out the spare and are in the process of replacing the flat tire.
Someone shouting "Your back tire is flat" at this point isn't helpful.

--
Michael <mhal...@gmail.com>

Russell Keith-Magee

unread,
Oct 16, 2010, 8:23:02 PM10/16/10
to django-d...@googlegroups.com
On Sunday, October 17, 2010, Yo-Yo Ma <baxters...@gmail.com> wrote:
> Gabriel
>
> You don't have to go to thesaurus.com with the intention of generating
> a more formidable argument. I was merely offering my opinion. Playing
> devil's advocate should be regarded as counter constructive. If I see
> a man about to throw an egg at an otherwise clean wall, I don't need
> to offer him an alternative weapon in order to tell him it's not a
> good idea to throw eggs at clean walls. I take a more hueristic
> approach to my suggestions. If something is obviously not 100% ideal,
> will obviously lead to problems in the near future, and doesn't need
> to be done right away (view functions work fine), why do it? Why not
> wait until something that is obviously correct comes about? As the
> wiki states, there are many implementations out there. With many more
> something really right will come. Complaining about a passer by with
> an opinion and suggesting that they "help" by writing code is much
> like asking a guy who shouts, "Your back tire is flat." to fix your
> tire or go away. Take advice or leave it. Don't complain when you get
> it.

Before this discussion gets out of hand, I'm going to call a stop to this.

Yo-yo - we made a decision as a community almost three years ago that
class-based views were something we want to pursue. Yes, function
based views "work", but they also have many significant limitations.
Those of us who have been members of the Django community for a long
time are well aware of these limitations, and adopting a class-based
view structure will address those limitations. You will have hopefully
noted the large number of core team members and long term community
members that have endorsed my "commit right now" proposal.

We made the decision to adopt class-based views a long time ago. As an
indication of this, class-based views were on the feature list for
Django 1.0, but had to be dropped due to a lack of time.

Unless someone comes up with a particularly compelling and specific
technical argument (I.e., essential capability X will not be possible,
or problem Y will cause significant problems) class-based views are
going to be added to Django. This much is a given. At this point, we
are just discussing the exact form, and even those discussions are
coming to conclusion.

If you don't want to use class-based views that result from this
multiple-year process, that is your choice. Nothing will compel you to
use them.

However, the time for abstract discussions has passed. And it's never
a good time to have an abstract discussion about abstract discussions,
which is where this conversation is going at a rate of knots.

If you have a *specific* technical argument to make, then make it. But
rehashing old ground doesn't help the debate. If you want to continue
those discussions with someone or you want to continue the
meta-argument, feel free to do so off list. Django-developers isn't an
appropriate forum.

Your,
Russ Magee %-)

Russell Keith-Magee

unread,
Oct 17, 2010, 11:58:22 AM10/17/10
to django-d...@googlegroups.com

I've just finished writing the first draft of the reference
documentation; and thanks to Andrew Godwin, we also have the bulk of
some great topic documentation.

Along the way, I've made some API tweaks as a result of some
documentation-driven development. These tweaks are mostly internal
structural things that won't have a huge effect unless you really get
involved with the mixins.

I should also be able to port the tutorial before I commit -- which,
barring objection, I will do tomorrow night my time (about 24 hours
from now). Speak now, etc etc.

Yours,
Russ Magee %-)

legutierr

unread,
Oct 17, 2010, 2:00:37 PM10/17/10
to Django developers


On Oct 17, 11:58 am, Russell Keith-Magee <russ...@keith-magee.com>
wrote:
> On Sat, Oct 16, 2010 at 12:45 AM, Russell Keith-Magee
>
> I should also be able to port the tutorial before I commit -- which,
> barring objection, I will do tomorrow night my time (about 24 hours
> from now). Speak now, etc etc.
>
> Yours,
> Russ Magee %-)

If it is too late for this, then just disregard, but I do have one
slight observation about the TemplateMixin. Might it be a good idea
to encourage alternate response mixins (JSONResponseMixin, etc.)
implemented by the community to implement and use get_response() and
get_context_instance() methods? If so, would it be a good idea to
implement a BaseResponseMixin that implements those methods, as well
as a `render_to_response` that raises NotImplementedError, that could
be subclassed?

This seems like a relatively inconsequential thing, but I thought I'd
just put it out there. Without it, I think the tendency would be for
alternate response mixins not to contain either of these methods
(which seem like useful hooks), or to just copy and paste what's
there.

Regards,
Ed Gutierrez

Łukasz Rekucki

unread,
Oct 17, 2010, 3:51:41 PM10/17/10
to django-d...@googlegroups.com
On 17 October 2010 20:00, legutierr <legu...@gmail.com> wrote:
>
>
> On Oct 17, 11:58 am, Russell Keith-Magee <russ...@keith-magee.com>
> wrote:
>> On Sat, Oct 16, 2010 at 12:45 AM, Russell Keith-Magee
>>
>> I should also be able to port the tutorial before I commit -- which,
>> barring objection, I will do tomorrow night my time (about 24 hours
>> from now). Speak now, etc etc.
>>
>> Yours,
>> Russ Magee %-)
>
> If it is too late for this, then just disregard, but I do have one
> slight observation about the TemplateMixin.  Might it be a good idea
> to encourage alternate response mixins (JSONResponseMixin, etc.)
> implemented by the community to implement and use get_response() and
> get_context_instance() methods?

I don't know if it makes sense for a JSON response to have a
get_context_instance(). The only common entry point left is
render_to_response(). There's a stub of "Not only HTML" section in
topic docs, so other formats won't be forgotten.


> If so, would it be a good idea to
> implement a BaseResponseMixin that implements those methods, as well
> as a `render_to_response` that raises NotImplementedError, that could
> be subclassed?

There is not much to implement. Having a method that raises
NotImplemetedError is bad in Mixins, as they can sometimes break your
code. In Python 2.6 we could make it an ABC, but we're stuck with 2.4.
Adding a ResponseMixin seems like a good idea to me.

>
> This seems like a relatively inconsequential thing, but I thought I'd
> just put it out there.  Without it, I think the tendency would be for
> alternate response mixins not to contain either of these methods
> (which seem like useful hooks), or to just copy and paste what's
> there.

If the alternate response mixin uses templates, then it will probably
just subclass TemplateResponseMixin. If it doesn't, then as I
mentioned before, I'm not sure you need the get_context_instance()
thing.

Currently, you can override only how successful responses are
rendered. I'm going to try to work on this on my branch, but I have a
small problem: In number of places, views raise Http404 which then get
rendered by the default 404 handler (which will render HTML, which is
useless for an AJAX view). I don't currently see an easy way, to
override this on a per-view basis with just a mixin. I could catch
Http404 exception, but it won't trigger middleware handling as it
normally does. Any suggestions ?

--
Łukasz Rekucki

George Sakkis

unread,
Oct 17, 2010, 5:29:23 PM10/17/10
to Django developers
On Oct 17, 5:58 pm, Russell Keith-Magee <russ...@keith-magee.com>
wrote:
It's not very important but it occured to me that we can solve the
second issue against the selected dispatch method ("If you do
AuthorDetail(foo=True).as_view(), instead of
AuthorDetail.as_view(foo=True), you will not get an exception, but
foo=True will effectively be ignored") by making "as_view" a
descriptor instead of a classmethod; see patch at http://gist.github.com/631306.

George

Łukasz Rekucki

unread,
Oct 17, 2010, 5:52:26 PM10/17/10
to django-d...@googlegroups.com

If you check the history of the previous thread, I proposed a similar
thing ;) but instead of a whole descriptor, you can just subclass the
classmethod decorator:

class classonlymethod(classmethod):
def __get__(self, instance, owner):
if instance is not None:
raise AttributeError("This method is availble only on the
view class.")
return super(classonlymethod, self).__get__(instance, owner)

# and later:

class View:
@classonlymethod
def as_view():
.....

--
Łukasz Rekucki

legutierr

unread,
Oct 17, 2010, 6:24:34 PM10/17/10
to Django developers


On Oct 17, 3:51 pm, Łukasz Rekucki <lreku...@gmail.com> wrote:

>
> Currently, you can override only how successful responses are
> rendered. I'm going to try to work on this on my branch, but I have a
> small problem: In number of places, views raise Http404 which then get
> rendered by the default 404 handler (which will render HTML, which is
> useless for an AJAX view). I don't currently see an easy way, to
> override this on a per-view basis with just a mixin. I could catch
> Http404 exception, but it won't trigger middleware handling as it
> normally does. Any suggestions ?
>
> --
> Łukasz Rekucki

One option might be to catch the Http404 in dispatch(), and then call
a "render_not_found" method if it is defined, and raise the exception
again if it is not:

def dispatch(self):
try:
...
return handler(response, *args, **kwargs)
except Http404:
if hasattr(self, "render_not_found"):
return self.render_not_found(response, *args, **kwargs)
else:
raise

render_not_found() could be optionally implemented by the render
response mixin, or left out entirely for standard 404 handling. Data-
oriented mixins could choose to implement it to provide a non-html
error response.

Russell Keith-Magee

unread,
Oct 17, 2010, 7:49:29 PM10/17/10
to django-d...@googlegroups.com

I contemplated this after looking at your bitbucket fork, but decided
against it. The ResponseMixin in your branch contains three methods:

* render_to_response() -- which must be overridden
* get_context_instance() -- which is of arguable utility in the general case
* get_response() -- which will probably need to be overridden in most
subclassing cases to provide a default content type.

Given that the only three methods in that mixin are either not
necessary or will need to be overridden, I decided that
reimplementation would ultimately make more sense. If this were Java
and types mattered, having the common base class might make sense, but
Python is fine about ducks, so we might as well exploit that fact.

However, you will note that the topic guide that Andrew prepared has a
section heading specifically targeted at JSON responses. That section
isn't written yet, but the idea is to put in a guide on how to handle
JSON responses as way to point out why template rendering has been
factored out in the way that it has.

Yours,
Russ Magee %-)

legutierr

unread,
Oct 17, 2010, 8:34:52 PM10/17/10
to Django developers
Thinking about it more, I think that the approach you took makes more
sense.

Regards,
Eduardo

On Oct 17, 7:49 pm, Russell Keith-Magee <russ...@keith-magee.com>
wrote:

Łukasz Rekucki

unread,
Oct 17, 2010, 9:01:03 PM10/17/10
to django-d...@googlegroups.com
On 18 October 2010 01:49, Russell Keith-Magee <rus...@keith-magee.com> wrote:
>
> However, you will note that the topic guide that Andrew prepared has a
> section heading specifically targeted at JSON responses. That section
> isn't written yet, but the idea is to put in a guide on how to handle
> JSON responses as way to point out why template rendering has been
> factored out in the way that it has.
>

I just pushed some changes on my fork. They introduce a bunch of
hooks, so that overriding how response instances are created is
easier. I'm not very happy, with catching Http404 in dispatch(), but I
can't think of a better solution at the moment. I also factored out a
ResponseMixin which now include this hooks. To construct a functional
view, you need to have at least one ResponseMixin in your MRO. Also,
creating a JSONMixin is pretty simple:

class JSONMixin(ResponseMixin):

def get_response_content(self, context):
return my_serialization_function(context), "application/json"

How to serialize your data properly is a different matter.

[1]: http://bitbucket.org/lqc/django

PS. Excuse me if this all doesn't make any sense, but i'm kinda half
asleep at 3 am.

--
Łukasz Rekucki

Gabriel Hurley

unread,
Oct 18, 2010, 7:17:56 PM10/18/10
to Django developers
I got my first real taste of the new API today by thoroughly proofing
the docs for class-based views. I just wanted to say that there's some
great stuff in there, and I give a big thanks to everyone who
contributed! I'm really looking forward to using the new class-based
views ASAP.

Thanks!

- Gabriel

On Oct 14, 9:19 am, Russell Keith-Magee <russ...@keith-magee.com>
wrote:
> Hi all,
>
> With the deadline for 1.3 alpha rapidly approaching, it's getting to
> crunch time for class-based views.
>
> The wiki page [1] now contains a good summary of the debate so far,
> showing why we have ended up at the "ClassBasedView.as_view()"
> deployment solution. I've also got a implementation up on my bitbucket
> repo [2] (in the class-based-views branch) that is integrated into the
> Django source tree.
>
> I've done an audit of the simple (template and redirect), detail and
> list views, and I'm reasonably happy with the feature set, feature
> parity with old-style function views, and test coverage. I've also
> checked that the outstanding generic-view tickets (#1282, #2367,
> #8378, #9150, #12669, #13753, and #13953) are solved or are solvable
> using the new class-based framework.
>
> The following things are still needed:
>
>  * An audit of create/update views.
>  * An audit of date views.
>  * Documentation, including
>     - changes to the tutorial
>     - topic documentation
>     - reference documentation
>     - a migration guide for function generic views to class-based generic views
>  * Feedback from the community on the API that has been exposed.
>  * Fixing Django's handling of PUT requests (this currently raises an
> expected failure in the test suite)
>
> Unfortunately, the 1.3 alpha deadline is Monday. Over the next couple
> of days, I intend to finish my audit of edit and date views, and make
> a start on at least reference documentation, but it's highly unlikely
> I'm going to get all the items on this list done by Monday.
>
> So - I'd like to field opinions on committing class-based views in an
> 'almost finished' state.
>
> I won't commit anything until at least my review of create/update and
> date views is complete. In particular, I'm not especially happy with
> the current state of the create/update views. I'd also like to see a
> couple of independent reviews of the API as a sanity check.
>
> Then, during the beta period, we will need to expand on the
> documentation and finish the other outstanding items. I would also
> expect to see some minor tweaks to the API as different use cases
> emerge. Some of these changes may be backwards incompatible, but I
> don't anticipate any widespread changes being necessary. Once we hit
> beta, I would anticipate that any backwards incompatible changes we
> need to make will have shaken out.
>
> One piece of evidence supporting this plan: history has shown us that
> we don't really get much serious testing of new features until they
> hit trunk, and we don't get the *really* serious testing until a final
> release is made. Getting an 'almost finished' version into trunk may
> actually help the feature develop faster than it would if we postponed
> to 1.4, hoping that it will mature in a separate branch.
>
> Any opinions or objections to this plan?
>
> [1]http://code.djangoproject.com/wiki/ClassBasedViews
> [2]http://bitbucket.org/freakboy3742/django- (class-based-views branch)
>
> Yours,
> Russ Magee %-)

Łukasz Rekucki

unread,
Oct 18, 2010, 8:04:59 PM10/18/10
to django-d...@googlegroups.com
On 19 October 2010 01:17, Gabriel Hurley <gab...@gmail.com> wrote:
> I got my first real taste of the new API today by thoroughly proofing
> the docs for class-based views. I just wanted to say that there's some
> great stuff in there, and I give a big thanks to everyone who
> contributed! I'm really looking forward to using the new class-based
> views ASAP.

Somehow related, I was wondering today, would it be a good idea to try
to rewrite contrib.auth views in terms of CBV, so that other parts of
Django could benefit. I'll have a free weekend, so I could get some
real work done this time. My other targets would be popular 3rd party
applications. If you know of any that have some really complicated
views, I think trying to rewrite them to CBV would be a good test of
the API, so send me a link :)

--
Łukasz Rekucki

Jacob Kaplan-Moss

unread,
Oct 18, 2010, 9:49:44 PM10/18/10
to django-d...@googlegroups.com
2010/10/18 Łukasz Rekucki <lrek...@gmail.com>:

> Somehow related, I was wondering today, would it be a good idea to try
> to rewrite contrib.auth views in terms of CBV, so that other parts of
> Django could benefit.

I'm not particularly clear on what other parts would benefit -- fill me in?

In general, I frown on refactoring just for the sake of refactoring:
there needs to be a clear reason *why* all that code needs to be moved
around. Code churn makes tracking down bugs harder (it obscures the
history of that part of the codebase) and can introduce new subtle
bugs to boot.

Instead, I tend to prefer an evolutionary approach: refactor outdated
bits of code as needed when fixing bugs, adding new features, etc.
Over time, old APIs become new ones.

IOW, if there's a compelling reason why we should refactor those
views, then by all means go for it. If you have to reach hard for a
reason, leave it for now.

Jacob

Will Hardy

unread,
Oct 18, 2010, 10:29:01 PM10/18/10
to django-d...@googlegroups.com
Whilst I agree that messing with contrib.auth is likely to break
something and create more work, I think it would be good for Django if
everyone in the Django community went and needlessly ported their real
world views to CBV, to expose any deficiencies in the framework before
release.

Even if the rewritten auth app isn't merged to trunk (yet), I imagine
it could be useful in testing the boundaries of the fresh framework.
If someone wants to put some hours on porting code that won't be
included, but has the off-chance of improving the CBV framework, it
would be very noble of them :-)

Cheers,

Will

Russell Keith-Magee

unread,
Oct 18, 2010, 11:10:06 PM10/18/10
to django-d...@googlegroups.com

I share Jacob's concern about making change for the sake of change.
This is especially important with contrib.auth. There have been long
running conversations about "fixing" contrib.auth to make it more
flexible. Since making contrib.auth more flexible may well involve
changes to the auth views, it would be premature to make changes now,
only to require more (potentially incompatible) changes in the near
future.

However, as an academic exercise, I agree that it's worth exploring.
contrib.comments would be another app that would benefit from an
academic exploration -- it's a complex collection of views that would
lend itself to subclassing.

Plus, some preliminary work now might provide a good base when we *do*
work out what changes need to be made to auth views.

Yours,
Russ Magee %-)

Łukasz Rekucki

unread,
Oct 19, 2010, 5:03:31 AM10/19/10
to django-d...@googlegroups.com
On 19 October 2010 05:10, Russell Keith-Magee <rus...@keith-magee.com> wrote:
> On Tue, Oct 19, 2010 at 10:29 AM, Will Hardy <e.wil...@gmail.com> wrote:
>> Whilst I agree that messing with contrib.auth is likely to break
>> something and create more work, I think it would be good for Django if
>> everyone in the Django community went and needlessly ported their real
>> world views to CBV, to expose any deficiencies in the framework before
>> release.
>>
>> Even if the rewritten auth app isn't merged to trunk (yet), I imagine
>> it could be useful in testing the boundaries of the fresh framework.
>> If someone wants to put some hours on porting code that won't be
>> included, but has the off-chance of improving the CBV framework, it
>> would be very noble of them :-)

I just kinda volunteered to do this, so I you send some code my way,
I'll take a look at it during the weekend.

> I share Jacob's concern about making change for the sake of change.
> This is especially important with contrib.auth. There have been long
> running conversations about "fixing" contrib.auth to make it more
> flexible. Since making contrib.auth more flexible may well involve
> changes to the auth views, it would be premature to make changes now,
> only to require more (potentially incompatible) changes in the near
> future.

I fully agree. It wasn't my intention to get this change into the
core, although it would make customizing views there a bit more
civilized.

>
> However, as an academic exercise, I agree that it's worth exploring.
> contrib.comments would be another app that would benefit from an
> academic exploration -- it's a complex collection of views that would
> lend itself to subclassing.
>
> Plus, some preliminary work now might provide a good base when we *do*
> work out what changes need to be made to auth views.
>

Yes, this is mostly an academic exercise, so I'll take a look at
contrib.comments too.


--
Łukasz Rekucki

Reply all
Reply to author
Forward
0 new messages