Wednesday, August 29, 2012

Re: Combinable generic CBVs

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.
> For example:
> class OnSaleMixin(ContextMixin) :
>         on_sale_queryset = Products.objects.filter(on_sale=True)
>         def get_context_data(self, **kwargs) :
>                 context = { 'on_sale_list': self.on_sale_queryset }
>                 context.update(kwargs)
>                 return super(OnSaleMixin, self).get_context_data(
>                         **context)
>
> class ProductList(ListView, OnSaleMixin) :
>         model = Products
>
> --
> Melvyn Sopacua


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.
Nobody ever complained that inheriting from a ListView and maybe
overriding one or two methods is hard to do. So the user case that
we need to optimize for is the one where difficulties lie and where
people have run into problems and complained about, blaming GCBVs
for being hard to use and debug.

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

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.

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