What Is New in Django 1.10
Django 1.10 introduces a mix of powerful new features, significant improvements, and the usual set of deprecations. This release focuses on enhancing the middleware layer, expanding the ORM's capabilities, and providing more flexibility for full-text search.
| Category | Key Changes |
|---|---|
| New Features | New-style middleware, Full-text search with PostgreSQL, Official support for Unicode usernames |
| Improvements | Customizable PostgreSQL index types, dbshell command management, New date template filter argument |
| Backwards Incompatibilities | django.core.urlresolvers module move, Old-style middleware deprecation |
| Deprecated Features | Support for direct assignment to a reverse foreign key relation, optparse in management commands |
How did middleware get a major overhaul?
The old middleware style, using MIDDLEWARE_CLASSES, is deprecated in favor of a new, simpler system using the MIDDLEWARE setting. This new approach treats middleware as callables with a well-defined __init__ and __call__ structure.
In practice, this change makes middleware behavior more explicit and easier to debug. The old style's inheritance-based model could lead to subtle bugs, especially with the order of execution. The new system is a welcome cleanup for a core part of the request/response cycle.
What full-text search capabilities were added for PostgreSQL?
Django 1.10 integrated PostgreSQL's built-in full-text search engine directly into the ORM. You can now use the SearchVector and SearchQuery classes to perform complex search operations without a third-party app like Haystack for basic needs.
This is a huge win for projects already using PostgreSQL. It simplifies the stack by leveraging the database's native strengths. You can search across multiple fields and even weight their importance directly in your queries.
How can I customize indexes for PostgreSQL?
The new django.contrib.postgres.indexes module allows you to create specialized indexes. The BrinIndex is particularly useful for very large tables with naturally ordered data, as it offers a smaller size and faster maintenance.
This gives developers more fine-grained control over database performance tuning directly from their Django models. It's a clear signal that Django is deepening its support for PostgreSQL-specific features.
What are the key backwards incompatible changes?
The django.core.urlresolvers module was moved to django.urls. All imports from the old location need to be updated. The old-style middleware system is also deprecated and will be removed in a future release.
These changes are straightforward to fix but are critical for a smooth upgrade. Running your test suite with warnings enabled will catch most of these issues. The URL resolver move consolidates URL-related functionality into a single, logical place.
FAQ
How do I upgrade my old middleware to the new style?
Convert your middleware classes from the old style (defining process_request, process_response methods) to a callable that takes a get_response argument in its __init__ and defines a __call__ method. Then update your MIDDLEWARE_CLASSES setting to the new MIDDLEWARE list.
Can I use the new PostgreSQL search if I'm on SQLite or MySQL?
No, the django.contrib.postgres.search features are specific to the PostgreSQL database backend. The search expressions and functionality rely on PostgreSQL's specific text search vectors and queries.
What happens if I don't update my imports from django.core.urlresolvers?
The old module will raise a deprecation warning in Django 1.10 and will be removed in a future version (Django 2.0). Your code will break at that point, so it's best to update the imports to django.urls during the 1.10 upgrade.
Is the old way of adding middleware completely broken now?
Not yet. The old MIDDLEWARE_CLASSES setting still works in 1.10 but its use is deprecated. You can run with both settings defined while you transition, but you should plan to fully migrate to the new MIDDLEWARE system.
What's the practical benefit of the new date template filter argument?
The date filter now accepts an optional argument to specify the timezone. This gives template authors more control over datetime presentation without having to pre-process all dates in the view, making templates more powerful and self-contained.