mirror of
https://github.com/django/django.git
synced 2024-12-23 01:25:58 +00:00
Fixed #30365 -- Fixed syntax highlighting in SQL examples.
Sphinx interprets some "%[a-z]" in SQL statements as a "Literal.String.Interpol" which leads to incorrect highlighting.
This commit is contained in:
parent
25b5eea8cd
commit
6fd9c9daa6
@ -14,7 +14,9 @@ A simple lookup example
|
||||
|
||||
Let's start with a simple custom lookup. We will write a custom lookup ``ne``
|
||||
which works opposite to ``exact``. ``Author.objects.filter(name__ne='Jack')``
|
||||
will translate to the SQL::
|
||||
will translate to the SQL:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
"author"."name" <> 'Jack'
|
||||
|
||||
@ -124,14 +126,18 @@ Next, let's register it for ``IntegerField``::
|
||||
IntegerField.register_lookup(AbsoluteValue)
|
||||
|
||||
We can now run the queries we had before.
|
||||
``Experiment.objects.filter(change__abs=27)`` will generate the following SQL::
|
||||
``Experiment.objects.filter(change__abs=27)`` will generate the following SQL:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE ABS("experiments"."change") = 27
|
||||
|
||||
By using ``Transform`` instead of ``Lookup`` it means we are able to chain
|
||||
further lookups afterwards. So
|
||||
``Experiment.objects.filter(change__abs__lt=27)`` will generate the following
|
||||
SQL::
|
||||
SQL:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE ABS("experiments"."change") < 27
|
||||
|
||||
@ -139,12 +145,16 @@ Note that in case there is no other lookup specified, Django interprets
|
||||
``change__abs=27`` as ``change__abs__exact=27``.
|
||||
|
||||
This also allows the result to be used in ``ORDER BY`` and ``DISTINCT ON``
|
||||
clauses. For example ``Experiment.objects.order_by('change__abs')`` generates::
|
||||
clauses. For example ``Experiment.objects.order_by('change__abs')`` generates:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... ORDER BY ABS("experiments"."change") ASC
|
||||
|
||||
And on databases that support distinct on fields (such as PostgreSQL),
|
||||
``Experiment.objects.distinct('change__abs')`` generates::
|
||||
``Experiment.objects.distinct('change__abs')`` generates:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... DISTINCT ON ABS("experiments"."change")
|
||||
|
||||
@ -178,7 +188,9 @@ indexes efficiently in some cases. In particular, when we use
|
||||
``change__lt=27``. (For the ``lte`` case we could use the SQL ``BETWEEN``).
|
||||
|
||||
So we would like ``Experiment.objects.filter(change__abs__lt=27)`` to generate
|
||||
the following SQL::
|
||||
the following SQL:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT .. WHERE "experiments"."change" < 27 AND "experiments"."change" > -27
|
||||
|
||||
@ -253,7 +265,9 @@ Next, let's register it::
|
||||
TextField.register_lookup(UpperCase)
|
||||
|
||||
Now, the queryset ``Author.objects.filter(name__upper="doe")`` will generate a case
|
||||
insensitive query like this::
|
||||
insensitive query like this:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE UPPER("author"."name") = UPPER('doe')
|
||||
|
||||
|
@ -1273,7 +1273,9 @@ subclass::
|
||||
word must be in at least one of ``search_fields``. For example, if
|
||||
``search_fields`` is set to ``['first_name', 'last_name']`` and a user
|
||||
searches for ``john lennon``, Django will do the equivalent of this SQL
|
||||
``WHERE`` clause::
|
||||
``WHERE`` clause:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
|
||||
AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')
|
||||
|
@ -445,11 +445,15 @@ Geometry example::
|
||||
# the intersection pattern (the pattern here is for 'contains').
|
||||
Zipcode.objects.filter(poly__relate=(geom, 'T*T***FF*'))
|
||||
|
||||
PostGIS SQL equivalent::
|
||||
PostGIS SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE ST_Relate(poly, geom, 'T*T***FF*')
|
||||
|
||||
SpatiaLite SQL equivalent::
|
||||
SpatiaLite SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE Relate(poly, geom, 'T*T***FF*')
|
||||
|
||||
@ -458,7 +462,9 @@ Raster example::
|
||||
Zipcode.objects.filter(poly__relate=(rast, 1, 'T*T***FF*'))
|
||||
Zipcode.objects.filter(rast__2__relate=(rast, 1, 'T*T***FF*'))
|
||||
|
||||
PostGIS SQL equivalent::
|
||||
PostGIS SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE ST_Relate(poly, ST_Polygon(rast, 1), 'T*T***FF*')
|
||||
SELECT ... WHERE ST_Relate(ST_Polygon(rast, 2), ST_Polygon(rast, 1), 'T*T***FF*')
|
||||
@ -477,7 +483,9 @@ Example::
|
||||
|
||||
Zipcode.objects.filter(poly__relate=(geom, 'anyinteract'))
|
||||
|
||||
Oracle SQL equivalent::
|
||||
Oracle SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE SDO_RELATE(poly, geom, 'anyinteract')
|
||||
|
||||
@ -552,7 +560,9 @@ Example::
|
||||
|
||||
Zipcode.objects.filter(poly__left=geom)
|
||||
|
||||
PostGIS equivalent::
|
||||
PostGIS equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE poly << geom
|
||||
|
||||
@ -571,7 +581,9 @@ Example::
|
||||
|
||||
Zipcode.objects.filter(poly__right=geom)
|
||||
|
||||
PostGIS equivalent::
|
||||
PostGIS equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE poly >> geom
|
||||
|
||||
@ -590,7 +602,9 @@ Example::
|
||||
|
||||
Zipcode.objects.filter(poly__overlaps_left=geom)
|
||||
|
||||
PostGIS equivalent::
|
||||
PostGIS equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE poly &< geom
|
||||
|
||||
@ -610,7 +624,9 @@ Example::
|
||||
|
||||
Zipcode.objects.filter(poly__overlaps_right=geom)
|
||||
|
||||
PostGIS equivalent::
|
||||
PostGIS equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE poly &> geom
|
||||
|
||||
@ -629,7 +645,9 @@ Example::
|
||||
|
||||
Zipcode.objects.filter(poly__overlaps_above=geom)
|
||||
|
||||
PostGIS equivalent::
|
||||
PostGIS equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE poly |&> geom
|
||||
|
||||
@ -648,7 +666,9 @@ Example::
|
||||
|
||||
Zipcode.objects.filter(poly__overlaps_below=geom)
|
||||
|
||||
PostGIS equivalent::
|
||||
PostGIS equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE poly &<| geom
|
||||
|
||||
@ -667,7 +687,9 @@ Example::
|
||||
|
||||
Zipcode.objects.filter(poly__strictly_above=geom)
|
||||
|
||||
PostGIS equivalent::
|
||||
PostGIS equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE poly |>> geom
|
||||
|
||||
@ -686,7 +708,9 @@ Example::
|
||||
|
||||
Zipcode.objects.filter(poly__strictly_below=geom)
|
||||
|
||||
PostGIS equivalent::
|
||||
PostGIS equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE poly <<| geom
|
||||
|
||||
|
@ -262,7 +262,9 @@ or they can be used to build a library of database functions::
|
||||
queryset.annotate(field_lower=Lower('field'))
|
||||
|
||||
But both cases will result in a queryset where each model is annotated with an
|
||||
extra attribute ``field_lower`` produced, roughly, from the following SQL::
|
||||
extra attribute ``field_lower`` produced, roughly, from the following SQL:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT
|
||||
...
|
||||
|
@ -195,7 +195,9 @@ AND whose ``headline`` is "Hello"::
|
||||
|
||||
Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello')
|
||||
|
||||
In SQL terms, that evaluates to::
|
||||
In SQL terms, that evaluates to:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ...
|
||||
WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello')
|
||||
@ -205,7 +207,9 @@ OR whose headline is "Hello"::
|
||||
|
||||
Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3)).exclude(headline='Hello')
|
||||
|
||||
In SQL terms, that evaluates to::
|
||||
In SQL terms, that evaluates to:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ...
|
||||
WHERE NOT pub_date > '2005-1-3'
|
||||
@ -1308,9 +1312,11 @@ generated by a ``QuerySet``.
|
||||
``params`` in order to protect against SQL injection attacks.
|
||||
|
||||
You also must not quote placeholders in the SQL string. This example is
|
||||
vulnerable to SQL injection because of the quotes around ``%s``::
|
||||
vulnerable to SQL injection because of the quotes around ``%s``:
|
||||
|
||||
"select col from sometable where othercol = '%s'" # unsafe!
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT col FROM sometable WHERE othercol = '%s' # unsafe!
|
||||
|
||||
You can read more about how Django's :ref:`SQL injection protection
|
||||
<sql-injection-protection>` works.
|
||||
@ -1337,8 +1343,9 @@ of the arguments is required, but you should use at least one of them.
|
||||
is greater than Jan. 1, 2006.
|
||||
|
||||
Django inserts the given SQL snippet directly into the ``SELECT``
|
||||
statement, so the resulting SQL of the above example would be something
|
||||
like::
|
||||
statement, so the resulting SQL of the above example would be something like:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT blog_entry.*, (pub_date > '2006-01-01') AS is_recent
|
||||
FROM blog_entry;
|
||||
@ -1357,7 +1364,9 @@ of the arguments is required, but you should use at least one of them.
|
||||
In this particular case, we're exploiting the fact that the query will
|
||||
already contain the ``blog_blog`` table in its ``FROM`` clause.
|
||||
|
||||
The resulting SQL of the above example would be::
|
||||
The resulting SQL of the above example would be:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT blog_blog.*, (SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id) AS entry_count
|
||||
FROM blog_blog;
|
||||
@ -1394,7 +1403,9 @@ of the arguments is required, but you should use at least one of them.
|
||||
|
||||
Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
|
||||
|
||||
...translates (roughly) into the following SQL::
|
||||
...translates (roughly) into the following SQL:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT * FROM blog_entry WHERE (foo='a' OR bar='a') AND (baz='a')
|
||||
|
||||
@ -2622,7 +2633,9 @@ Examples::
|
||||
Entry.objects.get(id__exact=14)
|
||||
Entry.objects.get(id__exact=None)
|
||||
|
||||
SQL equivalents::
|
||||
SQL equivalents:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE id = 14;
|
||||
SELECT ... WHERE id IS NULL;
|
||||
@ -2650,7 +2663,9 @@ Example::
|
||||
Blog.objects.get(name__iexact='beatles blog')
|
||||
Blog.objects.get(name__iexact=None)
|
||||
|
||||
SQL equivalents::
|
||||
SQL equivalents:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE name ILIKE 'beatles blog';
|
||||
SELECT ... WHERE name IS NULL;
|
||||
@ -2675,7 +2690,9 @@ Example::
|
||||
|
||||
Entry.objects.get(headline__contains='Lennon')
|
||||
|
||||
SQL equivalent::
|
||||
SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE headline LIKE '%Lennon%';
|
||||
|
||||
@ -2700,7 +2717,9 @@ Example::
|
||||
|
||||
Entry.objects.get(headline__icontains='Lennon')
|
||||
|
||||
SQL equivalent::
|
||||
SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE headline ILIKE '%Lennon%';
|
||||
|
||||
@ -2722,7 +2741,9 @@ Examples::
|
||||
Entry.objects.filter(id__in=[1, 3, 4])
|
||||
Entry.objects.filter(headline__in='abc')
|
||||
|
||||
SQL equivalents::
|
||||
SQL equivalents:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE id IN (1, 3, 4);
|
||||
SELECT ... WHERE headline IN ('a', 'b', 'c');
|
||||
@ -2733,7 +2754,9 @@ instead of providing a list of literal values::
|
||||
inner_qs = Blog.objects.filter(name__contains='Cheddar')
|
||||
entries = Entry.objects.filter(blog__in=inner_qs)
|
||||
|
||||
This queryset will be evaluated as subselect statement::
|
||||
This queryset will be evaluated as subselect statement:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE '%Cheddar%')
|
||||
|
||||
@ -2782,7 +2805,9 @@ Example::
|
||||
|
||||
Entry.objects.filter(id__gt=4)
|
||||
|
||||
SQL equivalent::
|
||||
SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE id > 4;
|
||||
|
||||
@ -2818,7 +2843,9 @@ Example::
|
||||
|
||||
Entry.objects.filter(headline__startswith='Lennon')
|
||||
|
||||
SQL equivalent::
|
||||
SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE headline LIKE 'Lennon%';
|
||||
|
||||
@ -2836,7 +2863,9 @@ Example::
|
||||
|
||||
Entry.objects.filter(headline__istartswith='Lennon')
|
||||
|
||||
SQL equivalent::
|
||||
SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE headline ILIKE 'Lennon%';
|
||||
|
||||
@ -2856,7 +2885,9 @@ Example::
|
||||
|
||||
Entry.objects.filter(headline__endswith='Lennon')
|
||||
|
||||
SQL equivalent::
|
||||
SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE headline LIKE '%Lennon';
|
||||
|
||||
@ -2877,7 +2908,9 @@ Example::
|
||||
|
||||
Entry.objects.filter(headline__iendswith='Lennon')
|
||||
|
||||
SQL equivalent::
|
||||
SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE headline ILIKE '%Lennon'
|
||||
|
||||
@ -2900,7 +2933,9 @@ Example::
|
||||
end_date = datetime.date(2005, 3, 31)
|
||||
Entry.objects.filter(pub_date__range=(start_date, end_date))
|
||||
|
||||
SQL equivalent::
|
||||
SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31';
|
||||
|
||||
@ -2912,7 +2947,9 @@ numbers and even characters.
|
||||
Filtering a ``DateTimeField`` with dates won't include items on the last
|
||||
day, because the bounds are interpreted as "0am on the given date". If
|
||||
``pub_date`` was a ``DateTimeField``, the above expression would be turned
|
||||
into this SQL::
|
||||
into this SQL:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE pub_date BETWEEN '2005-01-01 00:00:00' and '2005-03-31 00:00:00';
|
||||
|
||||
@ -2950,7 +2987,9 @@ Example::
|
||||
Entry.objects.filter(pub_date__year=2005)
|
||||
Entry.objects.filter(pub_date__year__gte=2005)
|
||||
|
||||
SQL equivalent::
|
||||
SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31';
|
||||
SELECT ... WHERE pub_date >= '2005-01-01';
|
||||
@ -2993,7 +3032,9 @@ Example::
|
||||
Entry.objects.filter(pub_date__month=12)
|
||||
Entry.objects.filter(pub_date__month__gte=6)
|
||||
|
||||
SQL equivalent::
|
||||
SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE EXTRACT('month' FROM pub_date) = '12';
|
||||
SELECT ... WHERE EXTRACT('month' FROM pub_date) >= '6';
|
||||
@ -3017,7 +3058,9 @@ Example::
|
||||
Entry.objects.filter(pub_date__day=3)
|
||||
Entry.objects.filter(pub_date__day__gte=3)
|
||||
|
||||
SQL equivalent::
|
||||
SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE EXTRACT('day' FROM pub_date) = '3';
|
||||
SELECT ... WHERE EXTRACT('day' FROM pub_date) >= '3';
|
||||
@ -3131,7 +3174,9 @@ Example::
|
||||
Event.objects.filter(time__hour=5)
|
||||
Event.objects.filter(timestamp__hour__gte=12)
|
||||
|
||||
SQL equivalent::
|
||||
SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE EXTRACT('hour' FROM timestamp) = '23';
|
||||
SELECT ... WHERE EXTRACT('hour' FROM time) = '5';
|
||||
@ -3156,7 +3201,9 @@ Example::
|
||||
Event.objects.filter(time__minute=46)
|
||||
Event.objects.filter(timestamp__minute__gte=29)
|
||||
|
||||
SQL equivalent::
|
||||
SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE EXTRACT('minute' FROM timestamp) = '29';
|
||||
SELECT ... WHERE EXTRACT('minute' FROM time) = '46';
|
||||
@ -3181,7 +3228,9 @@ Example::
|
||||
Event.objects.filter(time__second=2)
|
||||
Event.objects.filter(timestamp__second__gte=31)
|
||||
|
||||
SQL equivalent::
|
||||
SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE EXTRACT('second' FROM timestamp) = '31';
|
||||
SELECT ... WHERE EXTRACT('second' FROM time) = '2';
|
||||
@ -3204,7 +3253,9 @@ Example::
|
||||
|
||||
Entry.objects.filter(pub_date__isnull=True)
|
||||
|
||||
SQL equivalent::
|
||||
SQL equivalent:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE pub_date IS NULL;
|
||||
|
||||
@ -3224,7 +3275,9 @@ Example::
|
||||
|
||||
Entry.objects.get(title__regex=r'^(An?|The) +')
|
||||
|
||||
SQL equivalents::
|
||||
SQL equivalents:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL
|
||||
|
||||
@ -3248,7 +3301,9 @@ Example::
|
||||
|
||||
Entry.objects.get(title__iregex=r'^(an?|the) +')
|
||||
|
||||
SQL equivalents::
|
||||
SQL equivalents:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT ... WHERE title REGEXP '^(an?|the) +'; -- MySQL
|
||||
|
||||
|
@ -840,7 +840,9 @@ together. For example::
|
||||
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
|
||||
)
|
||||
|
||||
... roughly translates into the SQL::
|
||||
... roughly translates into the SQL:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT * from polls WHERE question LIKE 'Who%'
|
||||
AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')
|
||||
|
Loading…
Reference in New Issue
Block a user