Class-based views with Django

Simon Willison
DJUGL, 7th April 2009
Reusability

  A guiding principle of Django
   “Build applications, not projects”
   Generic views
   Thriving third part...
The Django contract

  A Django view is a function that takes a
  request object and returns a response object
  ORM, midd...
Generic views
  Encapsulate common patterns in web
  development
   List of things / page about each things
   Things that...
object_detail drawbacks
  You can’t swap the ORM for something else
  (without duck typing your own queryset)
  You have t...
newforms-admin

 De-coupled admin from the rest of Django
  Admin is just another application
 A new approach to customisa...
Finely grained permissions
class Entry(models.Model):
    title = models.CharField(max_length=255)
    author = models.For...
Finely grained permissions
class Entry(models.Model):
    title = models.CharField(max_length=255)
    author = models.For...
Finely grained permissions
class Entry(models.Model):
    title = models.CharField(max_length=255)
    author = models.For...
Finely grained permissions
class Entry(models.Model):
    title = models.CharField(max_length=255)
    author = models.For...
Finely grained permissions
class Entry(models.Model):
    title = models.CharField(max_length=255)
    author = models.For...
Finely grained permissions
class Entry(models.Model):
    title = models.CharField(max_length=255)
    author = models.For...
Objects can be views

  A Django view is a function that takes a
  request object and returns a response object
  A Django...
Objects can be views

  A Django view is a function that takes a
  request object and returns a response object
  A Django...
Example: restview.py
http://www.djangosnippets.org/snippets/1071/
django_openid

 Next generation of my django-openid project
 Taken a lot longer than I expected
 Extensive use of class-ba...
Ideas from django_openid

  Everything should go through a render() method
  Every template inherits from base_template
  ...
TemplateResponse
 If you render_to_response, a subclass can’t
 override and reuse your method while
 modifying the context...
Class-based generic views


  Ticket #6735
  Didn’t quite make 1.1; scheduled for 1.2
Subclassable decorators

      ratelimitcache is a decorator that
      implements rate limiting for a Django view
      I...
Extending the contract

  Django view: take request / return response
  Django middleware: take request / return response
...
Thank you
Class-based views with Django
Upcoming SlideShare
Loading in...5
×

Class-based views with Django

13,150

Published on

Talk given at DJUGL in London on the 7th April 2009

Published in: Technology
0 Comments
18 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
13,150
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
214
Comments
0
Likes
18
Embeds 0
No embeds

No notes for slide

Class-based views with Django

  1. 1. Class-based views with Django Simon Willison DJUGL, 7th April 2009
  2. 2. Reusability A guiding principle of Django “Build applications, not projects” Generic views Thriving third party ecosystem
  3. 3. The Django contract A Django view is a function that takes a request object and returns a response object ORM, middleware, template language, forms, authentication system, admin, sites etc are all optional extras
  4. 4. Generic views Encapsulate common patterns in web development List of things / page about each things Things that are archived by date Things you can create/update/delete Let’s look at the code for object_detail
  5. 5. object_detail drawbacks You can’t swap the ORM for something else (without duck typing your own queryset) You have to use RequestContext You can’t modify something added to the context; you can only specify extra_context That’s despite a great deal of effort going in to making the behaviour customisable
  6. 6. newforms-admin De-coupled admin from the rest of Django Admin is just another application A new approach to customisation Powerful subclassing pattern
  7. 7. Finely grained permissions class Entry(models.Model): title = models.CharField(max_length=255) author = models.ForeignKey('auth.User') class EntryAdmin(admin.ModelAdmin): exclude = ('author',) def queryset(self, request): queryset = super(EntryAdmin, self).queryset(request) return queryset.filter(author = request.user) def save_model(self, request, obj, form, change): obj.author = request.user obj.save() def has_change_permission(self, request, ojb=None): if not obj: return True # access to change list return obj.author == request.user has_delete_permission = has_change_permission admin.site.register(Entry, EntryAdmin)
  8. 8. Finely grained permissions class Entry(models.Model): title = models.CharField(max_length=255) author = models.ForeignKey('auth.User') class EntryAdmin(admin.ModelAdmin): exclude = ('author',) def queryset(self, request): queryset = super(EntryAdmin, self).queryset(request) return queryset.filter(author = request.user) def save_model(self, request, obj, form, change): obj.author = request.user obj.save() def has_change_permission(self, request, ojb=None): if not obj: return True # access to change list return obj.author == request.user has_delete_permission = has_change_permission admin.site.register(Entry, EntryAdmin)
  9. 9. Finely grained permissions class Entry(models.Model): title = models.CharField(max_length=255) author = models.ForeignKey('auth.User') class EntryAdmin(admin.ModelAdmin): exclude = ('author',) def queryset(self, request): queryset = super(EntryAdmin, self).queryset(request) return queryset.filter(author = request.user) def save_model(self, request, obj, form, change): obj.author = request.user obj.save() def has_change_permission(self, request, ojb=None): if not obj: return True # access to change list return obj.author == request.user has_delete_permission = has_change_permission admin.site.register(Entry, EntryAdmin)
  10. 10. Finely grained permissions class Entry(models.Model): title = models.CharField(max_length=255) author = models.ForeignKey('auth.User') class EntryAdmin(admin.ModelAdmin): exclude = ('author',) def queryset(self, request): queryset = super(EntryAdmin, self).queryset(request) return queryset.filter(author = request.user) def save_model(self, request, obj, form, change): obj.author = request.user obj.save() def has_change_permission(self, request, ojb=None): if not obj: return True # access to change list return obj.author == request.user has_delete_permission = has_change_permission admin.site.register(Entry, EntryAdmin)
  11. 11. Finely grained permissions class Entry(models.Model): title = models.CharField(max_length=255) author = models.ForeignKey('auth.User') class EntryAdmin(admin.ModelAdmin): exclude = ('author',) def queryset(self, request): queryset = super(EntryAdmin, self).queryset(request) return queryset.filter(author = request.user) def save_model(self, request, obj, form, change): obj.author = request.user obj.save() def has_change_permission(self, request, ojb=None): if not obj: return True # access to change list return obj.author == request.user has_delete_permission = has_change_permission admin.site.register(Entry, EntryAdmin)
  12. 12. Finely grained permissions class Entry(models.Model): title = models.CharField(max_length=255) author = models.ForeignKey('auth.User') class EntryAdmin(admin.ModelAdmin): exclude = ('author',) def queryset(self, request): queryset = super(EntryAdmin, self).queryset(request) return queryset.filter(author = request.user) def save_model(self, request, obj, form, change): obj.author = request.user obj.save() def has_change_permission(self, request, ojb=None): if not obj: return True # access to change list return obj.author == request.user has_delete_permission = has_change_permission admin.site.register(Entry, EntryAdmin)
  13. 13. Objects can be views A Django view is a function that takes a request object and returns a response object A Django view is a callable that takes a request object and returns a response object
  14. 14. Objects can be views A Django view is a function that takes a request object and returns a response object A Django view is a callable that takes a request object and returns a response object Just define __call__() on the class
  15. 15. Example: restview.py http://www.djangosnippets.org/snippets/1071/
  16. 16. django_openid Next generation of my django-openid project Taken a lot longer than I expected Extensive use of class-based customisation
  17. 17. Ideas from django_openid Everything should go through a render() method Every template inherits from base_template Every decision should be a method Every form should come from a method Every model interaction should live in a method
  18. 18. TemplateResponse If you render_to_response, a subclass can’t override and reuse your method while modifying the context or template Solution: return TemplateResponse( request, 'article.html', context ) auth.py line 65
  19. 19. Class-based generic views Ticket #6735 Didn’t quite make 1.1; scheduled for 1.2
  20. 20. Subclassable decorators ratelimitcache is a decorator that implements rate limiting for a Django view It’s a class disguised as a function, using the __call__ method You can subclass it to customise its behaviour http://github.com/simonw/ratelimitcache/tree/master
  21. 21. Extending the contract Django view: take request / return response Django middleware: take request / return response Django application: take request / return response Django urlconf: take request / return response Django site: take request / return response
  22. 22. Thank you
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×