diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index e87a27a9e08..f21887c6bd1 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -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 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 + `_ using the `QuerySet.extra + keyword `_ + 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:: You should be very careful whenever you use ``extra()``. Every time you use diff --git a/docs/topics/db/optimization.txt b/docs/topics/db/optimization.txt index 8847663b1b4..52238bd714d 100644 --- a/docs/topics/db/optimization.txt +++ b/docs/topics/db/optimization.txt @@ -130,12 +130,12 @@ For instance: If these aren't enough to generate the SQL you need: -Use ``QuerySet.extra()`` ------------------------- +Use ``RawSQL`` +-------------- -A less portable but more powerful method is -:meth:`~django.db.models.query.QuerySet.extra()`, which allows some SQL to be -explicitly added to the query. If that still isn't powerful enough: +A less portable but more powerful method is the +:class:`~django.db.models.expressions.RawSQL` expression, which allows some SQL +to be explicitly added to the query. If that still isn't powerful enough: Use raw SQL -----------