>> Class based generic views still have the major drawbacks of the >> previous version. They are a more powerful, more complicated version, >> but they're still a red-herring. > > Can you elaborate on this ? Taking your original concerns:
Sure. First of all, I'm not opposed to class based views, class views could allow for some cool behavior like class.as_html(), class.as_json(). I also think direct_to_template and redirect are ok. They are routing functions that make sense to include in the routing file (urls.py). I think in general the question should be asked: If generic views didn't exist, how would it change Django? I think the answer is, it would change it for the better. Django wouldn't loose any functionality, it would just loose a lot of complexity and adoption-barrier-creating confusion. Someone mentioned that generic views were there so non programmers could create apps. If this is the case, I would laud the intent. But, It strikes me as a non starter. How many people are there who could adequately use the other parts of the framework yet for whom learning to write a function that receives a request object and returns a response object is too complicated? How freaking hard is it to write def my_view(request, id=id): my_object = get_object_or_404('model', object_id=id) return render_to_response("my_template", locals()) Seriously, that's a generic detail view. Do we really need an entire shadow framework of routing to avoid writing these two lines? Further, that function is 100% extensible. Instead of spending half the tutorial on confusing people by introducing generic views, why not give them that function and say "if you need to do this repetative task, copy this and modify it?" Q: What if I need to modify the object, or check a value? A: write a single line of code that does just that. instead of A: pass supercalifragalistic as a value when invoking the generic view function. >> * You don't end up saving many keystrokes unless you have 3 or more >> views that are going to use the same info_dict. > > That sounds like a general rule for all things "generic" - if you > don't have similar problems, you must have different solutions. If you > have a couple of views that are almost similar, you can create a > common base class and make final tweaks as parameters to the as_view() > function. Let me turn the question back around. What is the most code/keystrokes/work/time you've ever seen generic views save? Do they ever reduce the short term work measured in keystrokes by half? Generic views don't provide enough value to justify the increased complexity. Iphones could have three or five buttons at the bottom of the screen but they don't because simplicity is almost always less costly over the long run than complexity. See below for my opinion on sub-classing class based generic views. > > * They can't be tweaked or changed much before you have to move the > code to the views file, destroying the keystroke savings. > > Class-based views are designed to solve exactly this problem. By > creating a subclass you can customize the parts you want and reuse > others. If the current API doesn't suite your needs, please do say. > I'm not going to argue it's perfect, but it surely is the right > direction :) Is sub classing a generic view really easier than writing a function? If you have repetitive behavior there are a number of easy ways to extract that behavior: Option 1: Write a function Option 2: Write a decorator, and wrap your function in that decorator. Option 3: Use a class based generic view. Say I have a group, and only members of the group are allowed to view certain information. def get_private_information(request, group_id): ensure user logged in ensure user is member of group get group info render_to_response(template, group_info) If I have a few kinds of private information the ensure statements are going to be repetative. Auth already has @login_required, so that leaves one piece of logic to extract. Option 1: def fail_if_not_group_member(request, group_id) group_list = Group.objects.get(id=group_id).as_list() if request.user in group_list: return True else: raise PermissionDenied Then in the get_private_information function, you just call "fail_if_not_group_member()" and unless you trap the exception, it becomes a 403 page. Option 2: Write a decorator function that has the same behavior as the fn in option 1, and then define your get_private_info function like this: @login_required @ensure_is_member def get_private_information(request, group_id): Option 3: Extend the appropriate generic view to do the checking. In this case, an extended generic view is like a Mule - the sterile offspring of breeding a regular view function and a generic view. Sure you can extend it to a certain point, but how much work are you really saving vs. using a regular view function? And is that savings (if it exists at all) worth the constrained ability to modify your function later? Sub classing MAKES GENERIC VIEWS WORSE because they take all of the work of a regular view function, and the end result is a less extensible/capable result. > > * Second syntax for doing the same thing makes Django harder to learn. > > I don't understand this one. Is this targeted at old generic views or > the new views ? When you're learning a new system, if there is one way to do it it takes 1 unit of work. If there are 2 ways to do it it takes 3 units of work - 1 to learn path a, 1 to learn path b, and 1 to learn when you should use a and b. This doesn't mean that having two ways to do things is bad, but it does mean that putting generic views in the tutorial before forms is downright malicious to the long term viability of the framework. People have to build mental models of how things work, and it takes real energy to build those models. If you take a person just learning a model and immediately tell them the model they're building is wrong, it predictably leads to confusion. Even worse, this extra confusion and work doesn't lead to the ability to do anything new. Stijin makes this point better than I do here http://stdout.be/2010/generic-views-suck/ This complaint is targeted at both kinds of generic views. I've heard a number of people say "i looked at the django tutorial and django seemed confusing/complicated/convoluted so I went with ...." > > Generic views usually can't solve your task out-of-the-box - this is > where the need for customization comes from. Old generic views let you > only customize small parts of variables. Class-based views take a > different approach - every time there is a (substantial) decision to > make, call a method on self. This way subclasses can redefine the way > that decision is made without the need to copy all of the view's code. Sure, that's one way to do it, but once you've done this you have done just as much work as writing a view function. This extensibility actually becomes a major problem becomes, as people are learning they could be spending that time and energy learning a full toolkit instead of a half-toolkit. How long is it going to be before we get requests on the list saying "Which generic view should I import if I want to get an object or create it if it doesn't already exists", or you get put on a project where the managers cousin extended the detail view to have create, edit, vote_up, and list methods? How long is it until you finish tweaking a generic view class and realize you've done 4 times the work it would have taken to just use regular view functions? The direction django has taken on this is: Problem: function based generic views have limited usefulness Solution: transform generic views into classes that have almost as many abilities as a regular view function. I think the real problem is: Generic views are of limited usefulness. And, generic views are introduced to newbies as a core part of the framework leading newbies to try to do more with them than they can really do. I think the real solution would be: Move Generic views to the attic, out of the tutorial, and teach newbies to do things right the first time. -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.