#6735 closed (fixed)
Class-based generic views
Reported by: | jkocherhans | Owned by: | David Larlet |
---|---|---|---|
Component: | Generic views | Version: | |
Severity: | Keywords: | ||
Cc: | Daniel Duan, floguy@…, David Larlet, Carl Meyer, Jannis Leidel, sciyoshi@…, vbmendes@…, anossov@…, mjmalone@…, taavi@…, narma.nsk@…, Oliver Beattie, Aaron C. de Bruyn, Jari Pennanen, brian@…, ssteinerX@…, drbob@…, ben@…, Alexander Koshelev, Chris Chambers, Brandon Konkle, Henrique Romano | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | yes |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Rewrite generic views to be class based, but leave the existing generic views as-is for now.
Attachments (6)
Change History (79)
by , 17 years ago
Attachment: | new-generic-views.diff added |
---|
comment:1 by , 17 years ago
comment:2 by , 17 years ago
Needs documentation: | set |
---|---|
Needs tests: | set |
The tests need to be fleshed out a little more, and we need a plan for backwards compatibility, but the classes themselves are fairly close, I think.
comment:3 by , 17 years ago
Cc: | added |
---|
comment:4 by , 17 years ago
comment:5 by , 17 years ago
Triage Stage: | Unreviewed → Design decision needed |
---|
by , 17 years ago
Attachment: | new-generic-views.2.diff added |
---|
by , 17 years ago
Attachment: | new-generic-views.3.diff added |
---|
comment:6 by , 17 years ago
post_save
is now on_success
and I've added hook to return the rendered template.
comment:7 by , 17 years ago
Needs tests: | unset |
---|---|
Triage Stage: | Design decision needed → Accepted |
Sorry about the mess of patch files. I forgot to check the "replace me" box. Anyhow, Adrian and Jacob are both in favor after a discussion today, so I'm changing status to Accepted.
comment:8 by , 17 years ago
Description: | modified (diff) |
---|---|
Summary: | Class-based generic create/update/delete views → Class-based generic views |
comment:9 by , 17 years ago
Description: | modified (diff) |
---|
by , 17 years ago
Attachment: | generic-views.2.diff added |
---|
comment:10 by , 17 years ago
The EditView class is passing back a exception when I use it with a model that has a field with editable set to False (editable=False).
I'm only starting out with python so please ignore this if the problem is at my end.
Traceback is here... http://dpaste.com/41195/
comment:11 by , 17 years ago
Cc: | added |
---|
comment:12 by , 17 years ago
This is great. it looks like one of the frequent patterns I'll be seeing is having to add some context vars a la extra_context. Presently I'm adding a render_response to the subclassed view and doing it there, might be nice to support a get_context_vars()
I think views as classes is a huge feature, might be nice to have the generic views inherit from a BaseView and BasePaginate view, etc. Personally the application I'm working on has a lot of pages with forms that filter the view somehow, so there will be a huge number of view subclasses.
comment:13 by , 16 years ago
Cc: | added |
---|
comment:14 by , 16 years ago
milestone: | → post-1.0 |
---|---|
Owner: | changed from | to
Status: | new → assigned |
Is anybody working on the docs for this? If not I'll try to give it some time later.
(No need to reply "no", just reply if "yes" ;))
comment:15 by , 16 years ago
Attached a possible class hierarchy. Not that what is drawn as class members are what would be passed to call() as parameters (it was easier to draw it this way).
comment:16 by , 16 years ago
For anyone interested in this ticket (scheduled post-1.0) current code (in-progress) can be taken from my git branch, raw, non-colored diff here.
Current code should be usable (passes tests). And provides wrappers to the old views, so if you can; Try the patch without touching your urls and let me know what happens.
comment:17 by , 16 years ago
Cc: | added |
---|
follow-up: 19 comment:18 by , 16 years ago
Question of the day, mostly for jacob and jkocherhans (it's DDN):
- Would you agree to add to DetailView and ListView (see current diff) an extra option: "allow_serialization" (and maybe "serialization_format='json'") and then, in the call() do:
if request.is_ajax() and self.allow_serialization: return serialized_stuff()
This is a pretty common pattern (if the request is AJAX return the object_list, or the object serializaed) and actually requires doing wrappers,
and with this ticket would mean people needing to do their own classes, so it would be nice to provide this (disabled by default).
It's generic! and simple, and disabled by default, but avoids needing wrappers/inheritance to get such a common thing ;) (Would also allow YUI, dojo, etc to provide better integration as there would be a standard way to get data for grids, etc from django).
comment:19 by , 16 years ago
Replying to telenieko:
Question of the day, mostly for jacob and jkocherhans (it's DDN):
- Would you agree to add to DetailView and ListView (see current diff) an extra option: "allow_serialization" (and maybe "serialization_format='json'") and then, in the call() do:
This seems more in the realm of the various REST projects going on, so I'd be -0. People are going to want to control which fields are serialized, and that is definitely out of scope for DetailView
and ListView
.
follow-up: 21 comment:20 by , 16 years ago
is the definition for ObjectListView not committed to base.py? I don't know how to use git yet, perhaps I'm missing something.
comment:21 by , 16 years ago
Replying to R. Bailey <bailey@akamai.com>:
is the definition for ObjectListView not committed to base.py? I don't know how to use git yet, perhaps I'm missing something.
I assume you refer to the imports in django/views/generic/list_detail.py, that was a typo I renamed ObjectListView and ObjectDetailView to ListView and DetailView to make them shorter.
Thanks for spotting the typo, that means there are more tests needed ;)
follow-up: 27 comment:23 by , 16 years ago
With 1.0 on the streen it's time to start with the killer features for 1.1 (yes I intend this one to go for 1.1 ehehe).
Question one: Would you love a ListEditView() which used FormSets to edit/create multiple objects? (Just like an EditView but for more than one form).
Question mostly for Jacob:
The documentation for the class based generic views (see current docs diff) has to document all the methods available for inheritance which makes the document itself a bit cumbersome (lots of details that people wanting to "just use" those views are not interested in). So, would it be reasonable to do a topics/generic-views.txt with the introduction and the usage details; And then put on ref/generic-views.txt the implementation details and how can one inherit/develop generic views on top of the new ones?
comment:24 by , 16 years ago
That's my main goal for 1.1 too. I hardly can find time for now but I keep an eye on it. Thanks for taking this.
comment:25 by , 16 years ago
Cc: | added |
---|
comment:26 by , 16 years ago
Cc: | added; removed |
---|
comment:27 by , 16 years ago
For the record, from IRC conversation:
Replying to telenieko:
Would you love a ListEditView() which used FormSets to edit/create multiple objects? (Just like an EditView but for more than one form).
That would be another ticket after this one gets in.
Would it be reasonable to do a topics/generic-views.txt with the introduction and the usage details; And then put on ref/generic-views.txt the implementation details and how can one inherit/develop generic views on top of the new ones?
Jacob is planning to do so for current generic views, so I'll do so for those ones.
comment:28 by , 16 years ago
Cc: | added |
---|
comment:29 by , 16 years ago
Cc: | added |
---|
comment:30 by , 16 years ago
Cc: | added; removed |
---|
comment:31 by , 16 years ago
Cc: | added |
---|
comment:33 by , 16 years ago
milestone: | → 1.1 beta |
---|
comment:34 by , 16 years ago
Cc: | added |
---|
comment:35 by , 16 years ago
Cc: | added; removed |
---|
comment:36 by , 16 years ago
milestone: | 1.1 beta → 1.2 |
---|
Looks like this won't make it; I didn't get it done.
follow-up: 38 comment:37 by , 16 years ago
Cc: | added |
---|
I think documenting the use of class-based views and providing a simple implementation would be a great addition to Django, but I don't think this is the right approach.
I've seen two methods of implementing class-based views, __call__
based and __init__
based. The attached patch uses the __call__
approach. Here's a quick example of an __init__
based class-view:
from django.http import HttpResponse class BaseView(HttpRespones): def __init__(self, request, *args, **kwargs): content = self.get(*args, **kwargs) super(MyView, self).__init__(content) def get(self): return 'Hello, world!'
The big gain here is that Django will instantiate a view instances per request, so you can actually store state in view objects. The __call__
based approach can be misleading/dangerous/confusing in this respect since the view instance is a global object that will be retained between requests. Even if you reset the state of the object at the beginning of each request, it's process local so it isn't thread safe.
The only thing the __init__
approach complicates is passing default arguments in during instantiation (e.g., model and post_save_redirect in the attached patch), but the url() function already solves that problem for function-based views by providing the kwargs argument, which works equally well here.
Unless anyone can think of some benefit to using the __call__
approach, I'd suggest we use __init__
instead.
comment:38 by , 16 years ago
Replying to mmalone:
I've seen two methods of implementing class-based views,
__call__
based and__init__
based. The attached patch uses the__call__
approach. Here's a quick example of an__init__
based class-view:
Hi mmalone,
This is getting a major re-thing/re-write by Jacob, taking an approach much more like Model classes, if I remember correctly, the thing was something like:
from django.views.generic import ListView class MyListView(ListView): # Base view for views that list objects queryset = MyModel.objects.all() paginate_by = 30 # You may override some methods here.
Then you'd pass the MyListView class to the URL patterns. init() would get URL parameters, while view configuration (what the current code here passes to init() would be on the class definition.
It's much more like Model classes, the only drawback is that you need to define you view class even for really simple stuff. But complex things get much nicer ;)
Hope Jacob can push current code sometime soon for everyone to see.
Thanks for commenting!
follow-up: 43 comment:40 by , 16 years ago
Anyone have a link to Jacob's code on github? I checked his projects but couldn't find it easily.
telenieko: re simple things becoming harder, you'll still be able to make function-based views so that's not really true!
comment:41 by , 16 years ago
It's in a branch of his fork of django: http://github.com/jacobian/django/tree/09cd9de875ee7a2d8f293329a69a2ca351445262/django/views/generic2
comment:42 by , 16 years ago
Replying to Alex:
Jacob's code is on github account.
Thanks! I should do "git remote update" more often :)
follow-up: 44 comment:43 by , 16 years ago
Replying to mmalone:
telenieko: re simple things becoming harder, you'll still be able to make function-based views so that's not really true!
I think those will be deprecated in favour of the class based ones.
comment:44 by , 16 years ago
Replying to telenieko:
I think those will be deprecated in favour of the class based ones.
That's kind of dumb. Django has always supported both, why explicitly "deprecate" one method when they're both well supported.
Also, I just took a look at Jacob's code and it looks like he's using the __call__
based approach, so my comments from above still apply. If you tell someone to write a class they're going to want to store state in instances, and I think that's going to be problematic.
comment:45 by , 16 years ago
Mike, he means the function generic views will be deprecated, not views in general.
comment:47 by , 16 years ago
Cc: | added |
---|
comment:48 by , 15 years ago
Cc: | added |
---|
comment:49 by , 15 years ago
I've just been poking through the branch on GitHub and it looks great, but just in the name of API consistency it looks like the API for the class based views does not match the API for Syndication Feeds.
Namely, in a feed, if you want to override (for example) 'title' you can either provide a method or a string and the feed will handle either value intelligently.
In the class based views (so far), if you want to override (for example) 'items' you can either set 'items' or you can override the method get_items. This isn't consistent.
I'm not sure if this is an issue but I thought I'd point it out.
comment:50 by , 15 years ago
Cc: | added |
---|
comment:51 by , 15 years ago
Cc: | removed |
---|
comment:52 by , 15 years ago
Cc: | added |
---|
comment:53 by , 15 years ago
Cc: | added |
---|
comment:54 by , 15 years ago
Cc: | added |
---|
comment:55 by , 15 years ago
milestone: | 1.2 |
---|---|
Version: | SVN |
comment:56 by , 15 years ago
Cc: | added |
---|
comment:57 by , 15 years ago
Cc: | added |
---|
comment:58 by , 15 years ago
Cc: | added |
---|
comment:59 by , 14 years ago
Owner: | changed from | to
---|---|
Status: | assigned → new |
Stealing that one for the djangocon.eu's sprint.
comment:60 by , 14 years ago
Status: | new → assigned |
---|
Our current work in progress is at http://github.com/bfirsh/django-class-based-views (forked from Jacob's one).
comment:61 by , 14 years ago
#13753 describes a reasonable feature request for generic views that should be integrated into this work, if at all possible.
comment:62 by , 14 years ago
Cc: | added |
---|
comment:63 by , 14 years ago
Cc: | added |
---|
comment:64 by , 14 years ago
Cc: | added; removed |
---|
comment:65 by , 14 years ago
Cc: | added |
---|
comment:66 by , 14 years ago
Cc: | added |
---|
comment:67 by , 14 years ago
Cc: | added |
---|
comment:68 by , 14 years ago
milestone: | → 1.3 |
---|
Wiki page with the current status of this ticket: http://code.djangoproject.com/wiki/ClassBasedViews
comment:69 by , 14 years ago
XViewMiddleware should be fixed if class-based views are added to Django: #13842
comment:70 by , 14 years ago
Cc: | removed |
---|
comment:71 by , 14 years ago
comment:72 by , 14 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
(In [14254]) Fixed #6735 -- Added class-based views.
This patch is the result of the work of many people, over many years.
To try and thank individuals would inevitably lead to many people
being left out or forgotten -- so rather than try to give a list that
will inevitably be incomplete, I'd like to thank *everybody* who
contributed in any way, big or small, with coding, testing, feedback
and/or documentation over the multi-year process of getting this into
trunk.
This ticket refs #3639 use newforms in generic create_update view