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

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Django 1.1 Tour

2,773

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,773
On Slideshare
0
From Embeds
0
Number of Embeds
3
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

    ×