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

Reply via email to