RC1 released November 16th
Can store any valid JSON (uses PG 9.4's jsonb type)
While custom indexing isn't supported in JSON, can create GIN indices manually.
- ORM support:
- arbitrarily deep path lookups - data__owner__other_pets__0__name
- contains - @> - query is a subset of data
- contained_by - <@ - data is a subset of query
- has_key - ? - key is present
- has_any_key - ?| - any key in a provided list is present
- has_keys - ?& - all keys in a provided list are present
- Postgres aggregation functions:
- ArrayAgg, StringAgg Statistical aggregates: correlation, regressions
https://docs.djangoproject.com/en/1.9/ref/contrib/postgres/aggregates/
- TransactionNow()
- useful to give all items within a transaction same update time
From 1.8:
- ArrayField
- HStoreField - probably avoid using this
- {...}RangeField
These new fields rely heavily on custom lookups & database functions, a powerful feature for using nicer database features without resorting to raw SQL every time.
Lookups: https://docs.djangoproject.com/en/1.9/ref/models/lookups/
@TextField.register_lookup
class Fulltext(Lookup):
lookup_name = 'ftsearch'
def as_sql(self, compiler, connection):
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params
return "to_tsvector('english', %s) @@ to_tsquery('english', %s)" % (lhs, rhs), params
# elsewhere...
Book.objects.filter(text__ftsearch='green', author='Dr. Seuss')
Functions: https://docs.djangoproject.com/en/1.9/ref/models/database-functions/
class TsVector(Func):
function = 'to_tsvector'
Book.objects.annotate(tsv=TsVector('english', F('text')))
Lots of contrib.gis was rewritten to use it and plenty of useful functions like Lower()/Upper()/Now() were added.
1.9 adds permission mixins for Class Based Views borrowing heavily from django-braces:
- AccessMixin
- LoginRequiredMixin
- PermissionRequiredMixin
- UserPassesTestMixin
All work similarly to how their decorator equivalents worked.
https://docs.djangoproject.com/en/1.9/topics/auth/default/#the-loginrequired-mixin
Set via AUTH_PASSWORD_VALIDATORS. Four provided by default:
- UserAttributeSimilarityValidator - not their name/email/etc.
- MinimumLengthValidator - set a minimum length
- CommonPasswordValidator - uses an included (configurable) list of 1000 most common passwords
- NumericPasswordValidator - not entirely numeric
https://docs.djangoproject.com/en/1.9/topics/auth/passwords/#password-validation
manage.py test --parallel
manage.py sendtestemail
- .delete() returns number of objects deleted (including cascades)
>>> num, types = Book.objects.delete() 3, {'bookstore.Book': 1, 'bookstore.Review': 2}simple_tag() can store results using 'as'
nicer admin template w/ flat look & SVG icons
test responses now have a .json() method, like requests' Response
on_commit() hook for post-transaction actions (cache invalidation & notifications)
And another hundred small things: https://docs.djangoproject.com/en/1.9/releases/1.9/
- syncdb
- no more automated fixture loading
- everything needs migrations
- Goodbye Python 3.2 and 3.3!
- tons of vendorized imports are gone as part of dropping support for old Python versions (dictconfig, importlib, tzinfo, unittest, etc.)
- IPAddressField
- replace w/ GenericIPAddressField
in 1.10, patterns() is finally going away
related_objects.add() now takes a bulk parameter that defaults to True
similarly, assignment now uses a manager.set() method instead of delete() and then add()
This is a lot faster than the old way but has a backwards-incompatible issue: objects must be already saved if you're using bulk which breaks some old code