views:

157

answers:

4

I'm currently learning Python and coming from a strong C# background. I keep hearing about doing things in a Pythonic way to take advantage of the dynamic nature of the language and some of it I get and some I don't.

I'm creating a site with Django and my approach to views is to use classes. My current thinking is to have a base class that has some stuff about the template and the model to use. This will have a default funky 404 type page with site search and stuff on then base all the other pages off this. So each area of the site will have its own EG News and all the model related functions and filtering will be in that class with a further class on top of that for HTML or AJAX requests. So you would have something like this:

\site\common\ViewBase

--\news\NewsBase(ViewBase)

--\news\HtmlView(NewsBase)

--\news\AJAXView(NewsBase)

URLs would be mapped like http://tld/news/latest maps to site.news.htmlview and http://tld/news//to/ will be also be mapped site.news.htmlview but the class will figure out what to do with the extra params.

This is pretty much what I would do in C# but the Django tutorial only shows using methods for views, making me wonder if this is not a very pythonic solution?

Thoughts?

Edit: After S.Lott comment about thread safety, Is it better to leave the functions as they are and have them create an instance of a class and call a method on it?

What I am looking for is a place to put common code for each section of the site for filtering the model, authentication for the site, etc

+4  A: 

Certainly there's nothing wrong with using a class for a view, provided you route the URL to an actual instance of a class and not just a class directly.

Ignacio Vazquez-Abrams
Be very, very careful about instance variables in the object. Django may be multi-threaded, and the only variables you can trust to be thread-safe are the request and your locals. The object's instance variables should be considered as **not** thread safe.
S.Lott
Thanks, I've seen quite a few blog posts about making a class callable, so feeling fairly comfortable with that :)
L2Type
Callable is easy. It's the instance variables that are the problem. If you don't use instance variables it leads to the question of why create a class when you're only using `__call__`? Why not make a function?
S.Lott
@S.Lott, I was talking to Ignacio at first but you make a good point. I've updated the question, thanks.
L2Type
+2  A: 

The Django admin does exactly this - look at the source code in django/contrib/admin.

The advantage of classes is that they are much easier to customize, for example you can add hooks for permission checking.

There is a proposal to move all existing generic views over to classes, it was supposed to get into 1.2 but failed to meet the deadline.

As the above poster points out, be very careful about handling instance variables - if you look at the admin classes, you see the request being passed to the various methods instead of relying on "self".

zeemonkee
A: 

Setting aside other concerns (such as thread-safety issues), it feels like there's a real possible danger here to cross the bright lines between Model / View / Template.

Or maybe it feels like a replacement for url dispatching (not that there's anything wrong with that :-). I'm not sure, but it just feels slightly off.

Peter Rowell
A: 

While class-based views are useful, inheritance may not be the right tool for this particular job. Helper functions and decorators are two great ways to factor out common code from your views. They also tend to be be more familiar/natural to other (python) coders who might work on your code.

I'm not sure what the best approach is in your case as I don't know how much you ultimately want to factor, just keep in mind that there are other ways to factor in python besides inheritance.

p.s. kudos for seeking out a pythonic solution.

ozan