Your SlideShare is downloading. ×
Django 1.1 Tour
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Django 1.1 Tour

2,744
views

Published on

Talk given at PyWeb-IL on 31st Aug 2009

Talk given at PyWeb-IL on 31st Aug 2009

Published in: Travel, Education

1 Comment
3 Likes
Statistics
Notes
  • Looks like a good presentation from the slides!
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
2,744
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
51
Comments
1
Likes
3
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
  • constraint names: can’t ./manage.py reset on 64-bit platforms
  • tests run inside transactions, subclass TransactionTestCase if you want to test transactional behavior
  • middleware is gone (unreliable), too unreliable for general-purpose use
  • BaseModelFormSet calls ModelForm.save(), problem if you were modifying self.initial in a model formset’s __init__
  • names of uploaded files not available until after save()
  • Lots of new features, many of them small improvements here-and there
    I’m only going to talk about five.
  • Of these, the first two will change your life
  • Of these, the first two will change your life
  • Summaries on queries
    Anytime you said “we’d need to iterate over the results...”
  • Easier to explain via showing
  • Aggregate is like get() or values() -- it doesn’t return a queryset
  • .aggregate() is like .get() -- it doesn’t return a queryset, so you can’t chain with it.
  • can give names to annotations
  • Filtering on annotations
  • Perform JOIN’s using __ notation
  • It takes a while to
  • filter/annotate not commutative
    annotate works on a query as it is at the time of the annotation.
  • allow you to reference model fields from inside a filter(), including doing arithmetic
  • Perform joins using the __ notation
  • Perform joins using the __ notation
  • Bulk actions, django comes with “delete”
    Really easy to write your own
  • Queryset.Update: speed, but model.save(), pre/post-save signals are bypassed.
  • Transcript

    • 1. Django 1.1 a tour of (some) new features Idan Gazit PyWeb-IL, August 31st 2009
    • 2. bit.ly/django11 release notes are your friend
    • 3. omg i haz to rewrite mai code?
    • 4. No! code you wrote for 1.0 should “Just Work” http://bit.ly/djangoapi
    • 5. With a few exceptions…
    • 6. With a few exceptions… constraint names on 64-bit platforms
    • 7. With a few exceptions… constraint names on 64-bit platforms transactions in tests
    • 8. With a few exceptions… constraint names on 64-bit platforms transactions in tests SetRemoteAddrFromForwardedFor middleware
    • 9. With a few exceptions… constraint names on 64-bit platforms transactions in tests SetRemoteAddrFromForwardedFor middleware saving of model formsets
    • 10. With a few exceptions… constraint names on 64-bit platforms transactions in tests SetRemoteAddrFromForwardedFor middleware saving of model formsets names of uploaded files
    • 11. Also… changed admin autodiscovery if your urlconf contains: (r'^admin/(.*)', admin.site.root), change it to be: (r'^admin/', include(admin.site.urls)),
    • 12. bit.ly/django11 release notes are your friend
    • 13. 1.1 new features 1290 tasty commits, 1200 bugs squashed
    • 14. 1.1 new features 10k new lines of documentation
    • 15. That’s a lot of new code. (at least there’s a lot of new docs)
    • 16. New Features! not an exhaustive list.
    • 17. • Aggregates • F() Expressions • Model improvements • Admin improvements • Comment Moderation
    • 18. OM GW • Aggregates TF BB • F() Expressions Q! ! • Model improvements • Admin improvements • Comment Moderation
    • 19. Aggregates
    • 20. What are aggregates? • aggregate() summary for entire query • annotate() summary per row returned
    • 21. Aggregate Examples Person Purchases first_name CharField thing CharField last_name CharField price DecimalField age IntField person FK What is the average age for all people? >>> Person.objects.aggregate(Avg(‘age’)) {‘age__avg’: 23.65}
    • 22. Aggregate Examples Person Purchases first_name CharField thing CharField last_name CharField price DecimalField age IntField person FK What is the average age for all people? >>> Person.objects.aggregate(Avg(‘age’), Min(‘age’), Max(‘age’)) {‘age__avg’: 23.65, ‘age__min’: 14, ‘age__max’:87}
    • 23. Aggregate Examples Person Purchases first_name CharField thing CharField last_name CharField price DecimalField age IntField person FK What is the average age for all people? >>> Person.objects.aggregate(Avg(‘age’), Min(‘age’), Max(‘age’)) {‘age__avg’: 23.65, ‘age__min’: 14, ‘age__max’:87} No Chaining!
    • 24. Aggregation functions • Avg(field): average of field • Min(field): min of field • Max(field): max of field • Sum(field): sum of all values in the field • Count(field, distinct): num of related objects via field • StdDev(field, sample) • Variance(field, sample)
    • 25. Annotation Person Purchases first_name CharField thing CharField last_name CharField price DecimalField age IntField person FK People ordered by number of purchases made q = Person.objects.annotate(Count(‘purchases’)).order_by( ‘-purchases__count’) >>> q[0] <Person: Material Girl> >>> q[0].purchases__count 4592810191
    • 26. Annotation Person Purchases first_name CharField thing CharField last_name CharField price DecimalField age IntField person FK People ordered by number of purchases made q = Person.objects.annotate(num_purchases=Count(‘purchases’)) .order_by(‘-num_purchases’) >>> q[0] <Person: Material Girl> >>> q[0].num_purchases 4592810191
    • 27. Annotation Person Purchases first_name CharField thing CharField last_name CharField price DecimalField age IntField person FK Which people have <=10 purchases? q = Person.objects.annotate( num_purchases=Count(‘purchases’)).filter(num_purchases__lte=10)
    • 28. Annotation Person Purchases first_name CharField thing CharField last_name CharField price DecimalField age IntField person FK Annotations work across JOINs: What is the average purchase price for purchases made by each person? Person.objects.annotate(min_price=Min(‘purchases__price’))
    • 29. Dizzy Yet? many possibilities
    • 30. Annotation Order is important! foo.filter().annotate() != foo.annotate().filter()
    • 31. F( ) expressions
    • 32. F( ) Expressions class Stock(models.Model): symbol = models.CharField() class TradingDay(models.Model): stock = models.ForeignKey(Stock, related_name="days") opening = models.DecimalField() closing = models.DecimalField() high = models.DecimalField() low = models.DecimalField()
    • 33. F( ) Expressions class Stock(models.Model): symbol = models.CharField() class TradingDay(models.Model): stock = models.ForeignKey(Stock, related_name="days") opening = models.DecimalField() closing = models.DecimalField() high = models.DecimalField() low = models.DecimalField() from django.db.models import F # Closed at least 50% up from open TradingDay.objects.filter(closing__gte=F('opening') * 1.5) # All downhill TradingDay.objects.filter(opening=F('high')) # Works across JOINs # Stocks that have days with <10pt loss in value Stock.objects.filter(days__closing__gte=F('days__opening')-10.0)
    • 34. F( ) Expressions Atomic DB Increment Operations! class MyModel(): ... counter = models.IntegerField() MyModel.objects.filter(id=someid).update(counter=F('counter')+1)
    • 35. Model Improvements
    • 36. Unmanaged Models • Useful for tables or DB views which aren’t under Django’s control • Work like regular models • No table creation during syncdb, tests, etc.
    • 37. Unmanaged Models class MyModel(): ... # some fields which match your existing table's column types class Meta: managed = False
    • 38. Proxy Models I already have a model, and want to change its python behavior without changing the underlying table structure.
    • 39. Proxy Models class MyProxy(MyModel): # no new fields! # but you can define new managers objects = SupaDupaProxyManager() proxy_specific_manager = PonyManager() class Meta: proxy = True ordering = ['not_the_original_ordering_field',] def my_proxy_method(self): # ... do something
    • 40. admin improvements
    • 41. Admin Actions
    • 42. Custom Admin Actions def add_cowbell(modeladmin, request, queryset): queryset.update(myfield='cowbell!')
    • 43. Custom Admin Actions def add_cowbell(modeladmin, request, queryset): queryset.update(myfield='cowbell!') add_cowbell.short_description = "More Cowbell!"
    • 44. Custom Admin Actions def add_cowbell(modeladmin, request, queryset): for obj in queryset: obj.myfield += 'cowbell!' obj.save() add_cowbell.short_description = "More Cowbell!"
    • 45. Custom Admin Actions def add_cowbell(modeladmin, request, queryset): for obj in queryset: obj.myfield += 'cowbell!' obj.save() add_cowbell.short_description = "More Cowbell!" class MusicAdmin(admin.ModelAdmin): list_display = ['artist', 'song'] ordering = ['artist',] actions = [add_cowbell]
    • 46. list_editable
    • 47. Generic Comment Moderation
    • 48. django.contrib.comments. moderation class BlogPost(models.Model): title = models.CharField() body = models.TextField() posted = models.DateTimeField() enable_comments = models.BooleanField() is_public = models.BooleanField()
    • 49. django.contrib.comments. moderation class BlogPost(models.Model): title = models.CharField() body = models.TextField() posted = models.DateTimeField() enable_comments = models.BooleanField() is_public = models.BooleanField() class BlogPostModerator(moderation.Moderator): email_notification = True enable_field = 'enable_comments' auto_close_field = 'posted' close_after = 14 moderation.moderator.register(BlogPost, BlogPostModerator)
    • 50. django.contrib.comments. moderation class BlogPostModerator(moderation.Moderator): email_notification = True enable_field = 'enable_comments' auto_close_field = 'posted' close_after = 14 def allow(comment, content_object, request): # return False to delete comment def moderate(comment, content_object, request): # return True to moderate comment moderation.moderator.register(BlogPost, BlogPostModerator)
    • 51. Random
    • 52. URL Namespaces (r'^myapp/', include('myapp.urls', namespace='foo', app_name='bar')) reverse(‘bar:mynamedurl’, args=[‘xyzzy’], current_app=‘foo’)
    • 53. For/Empty template tag {% for foo in bars %} <p>{{ foo.name }}</p> {% empty %} <p class="empty">No foos in bars!</p> {% endfor %}
    • 54. More Random! • forms: hidden_fields() / visible_fields() • auth using REMOTE_USER: IIS/mod_auth_sspi, mod_authnz_ldap, etc • safeseq template filter like safe but for lists • django.shortcuts.redirect() view: def my_view(request): ... return redirect('some-view-name', foo='bar')
    • 55. Many More!
    • 56. Fin. @idangazit idan@pixane.com
    • 57. Photo Credits • http://www.flickr.com/photos/josstyk/248920216/ • http://www.flickr.com/photos/mar00ned/3274556235/ • http://www.flickr.com/photos/ilumb/361819506/ • http://www.flickr.com/photos/womanofscorn/9163061/ • http://www.flickr.com/photos/ginnerobot/2549674296/ • http://www.flickr.com/photos/squaregraph/24869936 • http://www.flickr.com/photos/aresauburnphotos/3381681226 • http://www.flickr.com/photos/lwr/105783846/ • http://www.flickr.com/photos/jurvetson/447302275 • http://www.flickr.com/photos/leecullivan/240389468 • http://www.flickr.com/photos/pulpolux/3698819113