Class-based views with Django

  • 12,865 views
Uploaded on

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

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

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
12,865
On Slideshare
0
From Embeds
0
Number of Embeds
4

Actions

Shares
Downloads
212
Comments
0
Likes
17

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

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 Let’s look at the code for object_detail
  • 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. 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 define __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 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. Class-based generic views Ticket #6735 Didn’t quite make 1.1; scheduled for 1.2
  • 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. 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