What Is New in Django 1.9
Django 1.9 brings a host of new features and refinements, focusing on a more powerful ORM, enhanced security, and streamlined development workflows. The update includes significant additions like automatic password validation and a revamped admin interface. This release also continues the project's cleanup by deprecating older features.
| Category | Key Changes |
|---|---|
| New Features | Automatic password validation, New styling for admin, ArrayField for PostgreSQL |
| Improvements | Simplified model instance creation, New URL dispatcher syntax, Faster model saving |
| Backwards Incompatibilities | Context arguments removal, Changes to admin's inline formsets |
| Deprecated Features | django.contrib.contenttypes.generic, String view arguments in url() |
How does Django 1.9 improve application security?
The framework now includes built-in password validation. You can configure a list of validators that check for common weak passwords, user attribute similarity, and minimum length. This happens automatically during user creation and password change.
In practice, this means you no longer need to write custom validation logic for basic password strength requirements. The system is highly configurable, allowing you to define your own validator classes or adjust the parameters of the built-in ones.
What are the major new features for the ORM and database layer?
PostgreSQL users get a powerful new ArrayField for storing lists of data. The bulk_create() method now returns the list of created objects, often with primary keys, which is a huge timesaver.
You can also use the new Now() expression for database-side timestamps. For model instances, the refresh_from_db() method makes it simple to reload an object's data from the database, which is great for avoiding stale data in tests.
What changes were made to the admin interface?
The admin received a visual refresh to make it more modern and responsive. A more significant change is the new way to handle related object popups. The django.contrib.contenttypes.generic module was deprecated, so you'll need to use the new django.contrib.contenttypes.fields import path for generic foreign keys.
What syntax changes should developers be aware of?
The old way of passing a third context argument to custom template tags is gone. You must now use the simple_tag and inclusion_tag registration functions which handle this automatically. The url() function also no longer accepts a dotted Python path as a view argument; you must pass the callable view object itself.
For template loading, the old django.template.loaders.eggs.Loader was removed since Python eggs are no longer a common packaging format.
How does Django 1.9 handle deprecated features?
This release starts the deprecation process for several older patterns. The biggest one is the entire django.contrib.contenttypes.generic module, which is replaced by django.contrib.contenttypes.fields. Using string arguments to the url() function will now raise warnings, pushing developers to use the view callable directly.
These warnings are your signal to update your code. Running your tests with warnings enabled will help you catch these issues before they become errors in a future version.
FAQ
How do I enable the new password validators?
Add the AUTH_PASSWORD_VALIDATORS setting to your settings file. Django provides built-in validators for checking length, similarity to user attributes, and common passwords that you can include in this list.
My admin customizations broke. What happened?
The admin CSS classes were updated for the new design. If you had custom CSS that targeted old class names, you will need to update your stylesheets to match the new HTML structure.
Why is my custom template tag throwing an error?
You were likely using the old method of passing a context argument. You must now decorate your function with @register.simple_tag instead of using the takes_context argument on the now-removed register.tag method.
What's the deal with the ArrayField?
This is a PostgreSQL-specific field that allows you to store a list of values (e.g., integers, text) directly in a database column. It's not intended for use with other database backends.
bulk_create() didn't return objects before. How does it work now?
On PostgreSQL, the method can now return objects with primary keys set. For other databases, it returns the list of objects, but the primary keys will only be set if the backend supports it, which is a significant improvement for batch operations.