Fixed #25213 -- Discouraged use of QuerySet.extra()

Thanks Anssi Kääriäinen for the draft text and Simon Charette
for review.
This commit is contained in:
Tim Graham 2015-08-03 17:05:18 -04:00
parent 97fa7fe961
commit e8cd65f829
2 changed files with 33 additions and 5 deletions

View File

@ -1120,6 +1120,34 @@ Sometimes, the Django query syntax by itself can't easily express a complex
``QuerySet`` modifier — a hook for injecting specific clauses into the SQL ``QuerySet`` modifier — a hook for injecting specific clauses into the SQL
generated by a ``QuerySet``. generated by a ``QuerySet``.
.. admonition:: Use this method as a last resort
This is an old API that we aim to deprecate at some point in the future.
Use it only if you cannot express your query using other queryset methods.
If you do need to use it, please `file a ticket
<https://code.djangoproject.com/newticket>`_ using the `QuerySet.extra
keyword <https://code.djangoproject.com/query?status=assigned&status=new&keywords=~QuerySet.extra>`_
with your use case (please check the list of existing tickets first) so
that we can enhance the QuerySet API to allow removing ``extra()``. We are
no longer improving or fixing bugs for this method.
For example, this use of ``extra()``::
>>> qs.extra(
... select={'val': "select col from sometable where othercol = %s"},
... select_params=(someparam,),
... )
is equivalent to::
>>> qs.annotate(val=RawSQL("select col from sometable where othercol = %s", (someparam,)))
The main benefit of using :class:`~django.db.models.expressions.RawSQL` is
that you can set ``output_field`` if needed. The main downside is that if
you refer to some table alias of the queryset in the raw SQL, then it is
possible that Django might change that alias (for example, when the
queryset is used as a subquery in yet another query).
.. warning:: .. warning::
You should be very careful whenever you use ``extra()``. Every time you use You should be very careful whenever you use ``extra()``. Every time you use

View File

@ -130,12 +130,12 @@ For instance:
If these aren't enough to generate the SQL you need: If these aren't enough to generate the SQL you need:
Use ``QuerySet.extra()`` Use ``RawSQL``
------------------------ --------------
A less portable but more powerful method is A less portable but more powerful method is the
:meth:`~django.db.models.query.QuerySet.extra()`, which allows some SQL to be :class:`~django.db.models.expressions.RawSQL` expression, which allows some SQL
explicitly added to the query. If that still isn't powerful enough: to be explicitly added to the query. If that still isn't powerful enough:
Use raw SQL Use raw SQL
----------- -----------