Wednesday, August 29, 2012

Re: Combinable generic CBVs

On 29-8-2012 18:46, Rainy wrote:
> On Aug 29, 3:10 am, Melvyn Sopacua <m.r.sopa...@gmail.com> wrote:
>> On 29-8-2012 4:44, Rainy wrote:
>>
>>> When I use CBVs, I nearly always end up needing to mix different types in
>>> the same view, e.g. detail view and list view, list view and modelform
>>> view, etc. I really like CBVs but I feel this is the one shortcoming that I
>>> constantly run into that makes CBVs much less flexible and helpful than
>>> they could be.
>>
>> What are your real world cases for this? If you combine several models
>> to make up a page, you should consider writing your own mixins that
>> inherit only from ContextMixin and implement get_context_data() to add
>> the extra information.

<snip example>

> I will give some examples at the end of the message, but first I want
> to expand a bit on this idea.
>
> Let's say you have a detail CBV, FooView(DetailView): model = Foo ;
> and a list view, BarView(ListView): model = Bar .
>
> Now, combining different types of views is an extremely common case
> and you might say that the cases when you don't need to do that are
> usually so simple that existing GCBVs already handle them perfectly.

The list and detail view don't bite each other in many aspects. However,
as you will list in examples below, you usually don't have just one list
view per page. See below.

> I don't see any apparent reason why the two examples above can't
> be combined exactly in the same way you inherit each separate view:
> FooBarView(DetailView, ListView): detail_model=Foo; list_model=Bar.

Because how would you declare a second list model? And how would you
pick these up? Aside from making the routing through the model
difficult, this will also be a declaration nightmare.

> As a bonus, you don't have to decide which mixin to use and when
> overriding methods, you will know which instance variable and method
> handles detail and list objects.

Except when you need more than one list or detail or both.

> Here are a few examples where it would be useful, and I can find many
> more in my projects:
>
> - blog post: 3 CBVs: post, list of comments, comment form
> - search: FormView, ListView
> - photo album: detail view for album, listview of images
>
> I know each of these cases can be handled with current GCBVs but
> with a lot more effort and in a more verbose and error-prone way
> than what I'm proposing.

I don't see that:
class BlogView(CommentListMixin, CommentFormMixin, DetailView) :
model = BlogPosts

versus:
class BlogView(DetailView, ListView, CreateView) :
detail_model = BlogPost
list_model = Comments
form_model = Comments

I find the second version harder to read, more verbose to type and when
you want to support multiple models you will have to support some sort
of sequence or mapping. Not to mention how you'd handle template-coder
friendly names through context_object_name and similar.

Yes, the first version requires more work to code the mixins, but I
don't find them harder to debug either. In fact, pretty much only one
point where things can go wrong: get_context_data().

I can see your point and some of my issues with it may well be personal
preference, but I'm not sure if the Generic CBV's are a good base for
what you ask of them. I'm currently working on a RelatedModelMixin and
subsequently a FormsetMixin and I already feel like I'm coloring outside
the lines.
It's made me consider the fact that function based views are more
natural. A view really is a process where you hand it some info and it
returns what you asked for. It's less natural to think of it as a
collection of parts (objects) in a machine that work together to produce
your result.

However, once you know the order in which things are flowing through the
magic machine, debugging them isn't hard and things make a lot of sense
so I think part of the blame here is in the documentation which is in
fact improving a lot.

Last but not least, I think you should start writing if you feel
confident it can be done and is an improvement. It's the best way to
find out if your ideas can work or if another approach should be sought.

--
Melvyn Sopacua

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

No comments:

Post a Comment