Slide 1

Slide 1 text

Classy Views

Slide 2

Slide 2 text

What? Why? How? Classy Views

Slide 3

Slide 3 text

Replacement for Django’s old generic views New in 1.3, better in 1.4 So much more than the old views - a standard way to approach common tasks. Details, lists, archives, editing, template rendering Classy Views - What?

Slide 4

Slide 4 text

A few simple examples: Classy Views - What? # urls.py from django.conf.urls.defaults import patterns, url from django.views.generic import RedirectView urlpatterns = patterns('', url(r'^nowhere/$', RedirectView.as_view(url='/')), )

Slide 5

Slide 5 text

Classy Views - What? # urls.py urlpatterns = patterns('', url(r'^(?P\w+)/$', MyModelDetail.as_view()), ) # views.py from django.views.generic import DetailView class MyModelDetail(DetailView): model = MyModel template_name = 'a_different_template.html'

Slide 6

Slide 6 text

Classy Views - What? # views.py from django.views.generic import UpdateView class ChangeChild(UpdateView): model = MyModel slug_url_kwarg = 'child_slug' context_object_name = 'update_instance' def get_queryset(self): return self.model.filter(parent__slug=self.kwargs['slug']) def get_context_data(self, **kwargs): context = super(ChangeMyModel, self).get_context_data(**kwargs) context['mine'] = self.model.objects.for_user(self.request.user) return context def get_success_url(self): if self.object.owned_by(request.user): return self.object.get_absolute_url() return '/'

Slide 7

Slide 7 text

The ultimate tool for DRY view code No more extra_context=..., template_name=..., every_other_kwarg=... Easy customisation (so fantastic for libraries) Classy Views - Why?

Slide 8

Slide 8 text

Classy Views - Why?

Slide 9

Slide 9 text

Django sees it as the way forwards - the old generic views will not be in Django 1.5 Classy Views - Why?

Slide 10

Slide 10 text

Unit testing is now easy Classy Views - Why? # tests.py from django.test import TestCase class MyTests(TestCase): def test_view(self): obj = MyModel(slug='test-object') view = MyModelDetail(object=obj) templates = view.get_template_names() self.assertEqual(templates, [ 'custom/test-object_detail.html', 'myapp/mymodel_detail.html', ])

Slide 11

Slide 11 text

Why not? Performance - pretty minor hit https://github.com/FZambia/django-class-based- vs-function-based Classy Views - Why? Class Based View GET: 12.6605019569 Class Based View POST: 16.5869309902 Function Based View GET: 12.0667870045 Function Based View POST: 16.1339828968

Slide 12

Slide 12 text

MRO Spaghetti! Classy Views - Why? Happy Not Happy

Slide 13

Slide 13 text

Some common patterns: login_required and other functional decorators do it in urls.py decorate dispatch (with a Mixin obviously) class decorators Classy Views - How?

Slide 14

Slide 14 text

PrepareMixin HTTP method independent permission/sanity checking Classy Views - How? class PrepareMixin(object): def dispatch(self, request, *args, **kwargs) self.request = request self.args = args self.kwargs = kwargs resp = self.prepare() if resp: return resp return super(PrepareMixin, self).dispatch(...)

Slide 15

Slide 15 text

https://github.com/AndrewIngram/django-extra- views Multiple forms Formsets - both straight and inline Calendar month Classy Views - How?

Slide 16

Slide 16 text

ccbv.co.uk Classy Views - How?

Slide 17

Slide 17 text

Classy Views - How?