This may cause some backwards compatibility issues, but may also
resolve security issues in third party projects that fail to heed warnings
in our documentation.
Thanks Markus Holtermann for help with tests and docs.
The website only renders code blocks at 96 chars, and therefore
long code lines get wrapped. Manually breaking the lines prevents
the wrapping from occurring.
The new signature enables better support for routing RunPython and
RunSQL operations, especially w.r.t. reusable and third-party apps.
This commit also takes advantage of the deprecation cycle for the old
signature to remove the backward incompatibility introduced in #22583;
RunPython and RunSQL won't call allow_migrate() when when the router
has the old signature.
Thanks Aymeric Augustin and Tim Graham for helping shape up the patch.
Refs 22583.
As suggested by Anssi. This has the slightly strange side effect of
passing the expression to Expression.convert_value has the expression
passed back to it, but it allows more complex patterns of expressions.
Refactored compiler SELECT, GROUP BY and ORDER BY generation.
While there, also refactored select_related() implementation
(get_cached_row() and get_klass_info() are now gone!).
Made get_db_converters() method work on expressions instead of
internal_type. This allows the backend converters to target
specific expressions if need be.
Added query.context, this can be used to set per-query state.
Also changed the signature of database converters. They now accept
context as an argument.
Introduced the various shortcuts before explaining the more complex
parser/render functionality.
Also removed non-decorator syntax: it's been years since Django
supported a Python version without decorators.
consistent.
The following methods **should** be implemented, but are not required:
* Storage.delete()
* Storage.exists()
* Storage.listdir()
* Storage.size()
* Storage.url()
Updated documentation to reflect this fact and give a couple of examples
where some methods may not be implemented. Add a warning that not
implementing some methods will result in a partial (possibly broken)
interface.
Ticket: https://code.djangoproject.com/ticket/23376