class-based views with django

23
Class-based views with Django Simon Willison DJUGL, 7th April 2009

Upload: simon-willison

Post on 07-Nov-2014

18.771 views

Category:

Technology


6 download

DESCRIPTION

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

TRANSCRIPT

  • 1. Class-based views with Django Simon Willison DJUGL, 7th April 2009
  • 2. Reusability A guiding principle of Django Build applications, not projects Generic views Thriving third party ecosystem
  • 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. 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 Lets look at the code for object_detail
  • 5. object_detail drawbacks You cant swap the ORM for something else (without duck typing your own queryset) You have to use RequestContext You cant modify something added to the context; you can only specify extra_context Thats despite a great deal of effort going in to making the behaviour customisable
  • 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. 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. 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. 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. 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. 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. 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. 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. 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 dene __call__() on the class
  • 15. Example: restview.py http://www.djangosnippets.org/snippets/1071/
  • 16. django_openid Next generation of my django-openid project Taken a lot longer than I expected Extensive use of class-based customisation
  • 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. TemplateResponse If you render_to_response, a subclass cant override and reuse your method while modifying the context or template Solution: return TemplateResponse( request, 'article.html', context ) auth.py line 65
  • 19. Class-based generic views Ticket #6735 Didnt quite make 1.1; scheduled for 1.2
  • 20. Subclassable decorators ratelimitcache is a decorator that implements rate limiting for a Django view Its 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. 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. Thank you