salezica
salezica

Reputation: 76929

Django: class views, generic views, etc

I'm coming back to Django after a brief encounter with version 1.2, and now in version 1.3 the favored approach to views seems to be using classes.

Keeping in mind code style, maintainability and modularity: when should I use classes, and when functions? Should I always extend from generic class views (there seems to be no harm in using TemplateView), or should I use my own view callable objects?

Thanks in advance.

Upvotes: 5

Views: 759

Answers (2)

Torsten Engelbrecht
Torsten Engelbrecht

Reputation: 13486

There are in my opinion two cases for necessity of class-based(-generic)-views:

  • You really need generic functionality in your views and a little bit extra.
  • You write a resusable Django app and want to make it possible that others can extend your views.

For anything else use what you feel most comfortable with. As you said you basically good to go with extending from TemplateView and overwriting respective methods, though you could also use a function-based approach (and have to deal with render template calls by yourself). That's up to you in the end.

EDIT: One other advantage of class based views is that it lets you separate your code according to the request.method in a more cleaner manner and even returns 405 Method Not Allowed response codes when the wrong method is used. So you don't have to deal with lines like if request.method=='POST' or if request.method=='GET' at all and just extend a post or get method.

Upvotes: 4

tawmas
tawmas

Reputation: 7833

I find that class-based views help keep my code readable and streamlined.

Take, for example, the sample (function-based) view from the form documentation:

def contact(request):
    if request.method == 'POST': # If the form has been submitted...
        form = ContactForm(request.POST) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            # Process the data in form.cleaned_data
            # ...
            return HttpResponseRedirect('/thanks/') # Redirect after POST
    else:
        form = ContactForm() # An unbound form

    return render_to_response('contact.html', {
        'form': form,
    })

In the class-based equivalent, the boilerplate code and the nasty nested ifs disappear:

class Contact(FormView):
    template_name = 'contact.html'
    form_class = ContactForm
    success_url = '/thanks/'

    def form_valid(self, form):
        # Process the data in form.cleaned_data
        return super(Contact, self).form_valid(form)

Also, while you can always mix and match function-based and class-based views, I find that mixing styles in the same Django app tends to look quite messy. So, once I have a few views that really benefit from going class-based, it is an easy step to switch all the lot.

Upvotes: 7

Related Questions