django 1.1 tour

58
Idan Gazit PyWeb-IL, August 31 st 2009 Django 1.1 a tour of (some) new features

Upload: idan-gazit

Post on 15-Jan-2015

2.738 views

Category:

Travel


2 download

DESCRIPTION

Talk given at PyWeb-IL on 31st Aug 2009

TRANSCRIPT

Page 1: Django 1.1 Tour

Idan Gazit

PyWeb-IL, August 31st 2009

Django 1.1a tour of (some) new features

Page 2: Django 1.1 Tour
Page 3: Django 1.1 Tour

bit.ly/django11release notes are your friend

Page 4: Django 1.1 Tour

omg i haz to rewrite mai code?

Page 5: Django 1.1 Tour

No!

code you wrote for 1.0 should

“Just Work”

http://bit.ly/djangoapi

Page 6: Django 1.1 Tour

With a few exceptions…

Page 7: Django 1.1 Tour

With a few exceptions…

constraint names on 64-bit platforms

Page 8: Django 1.1 Tour

With a few exceptions…

constraint names on 64-bit platforms

transactions in tests

Page 9: Django 1.1 Tour

With a few exceptions…

constraint names on 64-bit platforms

transactions in tests

SetRemoteAddrFromForwardedFor middleware

Page 10: Django 1.1 Tour

With a few exceptions…

constraint names on 64-bit platforms

transactions in tests

SetRemoteAddrFromForwardedFor middleware

saving of model formsets

Page 11: Django 1.1 Tour

With a few exceptions…

constraint names on 64-bit platforms

transactions in tests

SetRemoteAddrFromForwardedFor middleware

saving of model formsets

names of uploaded files

Page 12: Django 1.1 Tour

Also…

changed admin autodiscovery

if your urlconf contains:(r'^admin/(.*)', admin.site.root),

change it to be:(r'^admin/', include(admin.site.urls)),

Page 13: Django 1.1 Tour

bit.ly/django11release notes are your friend

Page 14: Django 1.1 Tour

1.1 new features

1290 tasty commits, 1200 bugs squashed

Page 15: Django 1.1 Tour

1.1 new features

10k new lines of documentation

Page 16: Django 1.1 Tour

That’s a lot of new code.(at least there’s a lot of new docs)

Page 17: Django 1.1 Tour

New Features!not an exhaustive list.

Page 18: Django 1.1 Tour

• Aggregates

• F() Expressions

• Model improvements

• Admin improvements

• Comment Moderation

Page 19: Django 1.1 Tour

• Aggregates

• F() Expressions

• Model improvements

• Admin improvements

• Comment Moderation

OMGWTFBBQ!!

Page 20: Django 1.1 Tour

Aggregates

Page 21: Django 1.1 Tour

What are aggregates?

• aggregate()summary for entire query

• annotate()summary per row returned

Page 22: Django 1.1 Tour

Aggregate Examples

What is the average age for all people?

>>> Person.objects.aggregate(Avg(‘age’)){‘age__avg’: 23.65}

IntFieldage

first_name CharField

CharFieldlast_name

Person

person FK

thing CharField

DecimalFieldprice

Purchases

Page 23: Django 1.1 Tour

Aggregate Examples

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}

IntFieldage

first_name CharField

CharFieldlast_name

Person

person FK

thing CharField

DecimalFieldprice

Purchases

Page 24: Django 1.1 Tour

Aggregate Examples

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}

IntFieldage

first_name CharField

CharFieldlast_name

Person

person FK

thing CharField

DecimalFieldprice

Purchases

No Chaining!

Page 25: Django 1.1 Tour

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)

Page 26: Django 1.1 Tour

Annotation

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__count4592810191

IntFieldage

first_name CharField

CharFieldlast_name

Person

person FK

thing CharField

DecimalFieldprice

Purchases

Page 27: Django 1.1 Tour

Annotation

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_purchases4592810191

IntFieldage

first_name CharField

CharFieldlast_name

Person

person FK

thing CharField

DecimalFieldprice

Purchases

Page 28: Django 1.1 Tour

Annotation

Which people have <=10 purchases?

q = Person.objects.annotate( num_purchases=Count(‘purchases’)).filter(num_purchases__lte=10)

IntFieldage

first_name CharField

CharFieldlast_name

Person

person FK

thing CharField

DecimalFieldprice

Purchases

Page 29: Django 1.1 Tour

Annotation

Annotations work across JOINs:

What is the average purchase price for purchases made by each person?

Person.objects.annotate(min_price=Min(‘purchases__price’))

IntFieldage

first_name CharField

CharFieldlast_name

Person

person FK

thing CharField

DecimalFieldprice

Purchases

Page 30: Django 1.1 Tour

Dizzy Yet?many possibilities

Page 31: Django 1.1 Tour

Annotation

Order is important!

foo.filter().annotate() != foo.annotate().filter()

Page 32: Django 1.1 Tour

F( ) expressions

Page 33: Django 1.1 Tour

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()

Page 34: Django 1.1 Tour

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 openTradingDay.objects.filter(closing__gte=F('opening') * 1.5)# All downhillTradingDay.objects.filter(opening=F('high'))# Works across JOINs# Stocks that have days with <10pt loss in valueStock.objects.filter(days__closing__gte=F('days__opening')-10.0)

Page 35: Django 1.1 Tour

F( ) Expressions

Atomic DB Increment Operations!

class MyModel(): ... counter = models.IntegerField()

MyModel.objects.filter(id=someid).update(counter=F('counter')+1)

Page 36: Django 1.1 Tour

Model Improvements

Page 37: Django 1.1 Tour

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.

Page 38: Django 1.1 Tour

Unmanaged Models

class MyModel(): ... # some fields which match your existing table's column types class Meta: managed = False

Page 39: Django 1.1 Tour

Proxy Models

I already have a model, and want to change its python behavior without changing the underlying table structure.

Page 40: Django 1.1 Tour

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

Page 41: Django 1.1 Tour

admin improvements

Page 42: Django 1.1 Tour

Admin Actions

Page 43: Django 1.1 Tour

Custom Admin Actions

def add_cowbell(modeladmin, request, queryset): queryset.update(myfield='cowbell!')

Page 44: Django 1.1 Tour

Custom Admin Actions

def add_cowbell(modeladmin, request, queryset): queryset.update(myfield='cowbell!')

add_cowbell.short_description = "More Cowbell!"

Page 45: Django 1.1 Tour

Custom Admin Actions

def add_cowbell(modeladmin, request, queryset): for obj in queryset: obj.myfield += 'cowbell!' obj.save()

add_cowbell.short_description = "More Cowbell!"

Page 46: Django 1.1 Tour

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]

Page 47: Django 1.1 Tour

list_editable

Page 48: Django 1.1 Tour

Generic Comment Moderation

Page 49: Django 1.1 Tour

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()

Page 50: Django 1.1 Tour

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)

Page 51: Django 1.1 Tour

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)

Page 52: Django 1.1 Tour

Random

Page 53: Django 1.1 Tour

(r'^myapp/', include('myapp.urls', namespace='foo', app_name='bar'))

reverse(‘bar:mynamedurl’, args=[‘xyzzy’], current_app=‘foo’)

URL Namespaces

Page 54: Django 1.1 Tour

{% for foo in bars %} <p>{{ foo.name }}</p>{% empty %} <p class="empty">No foos in bars!</p>{% endfor %}

For/Empty template tag

Page 55: Django 1.1 Tour

• forms: hidden_fields() / visible_fields()

• auth using REMOTE_USER: IIS/mod_auth_sspi, mod_authnz_ldap, etc

• safeseq template filterlike safe but for lists

• django.shortcuts.redirect() view:def my_view(request): ... return redirect('some-view-name', foo='bar')

More Random!

Page 56: Django 1.1 Tour

Many More!

Page 58: Django 1.1 Tour

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