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:
Daniel Musketa 2019-04-13 15:49:55 +02:00 committed by Mariusz Felisiak
parent 25b5eea8cd
commit 6fd9c9daa6
6 changed files with 151 additions and 52 deletions

View File

@ -14,7 +14,9 @@ A simple lookup example
Let's start with a simple custom lookup. We will write a custom lookup ``ne`` 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')`` 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' "author"."name" <> 'Jack'
@ -124,14 +126,18 @@ Next, let's register it for ``IntegerField``::
IntegerField.register_lookup(AbsoluteValue) IntegerField.register_lookup(AbsoluteValue)
We can now run the queries we had before. 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 SELECT ... WHERE ABS("experiments"."change") = 27
By using ``Transform`` instead of ``Lookup`` it means we are able to chain By using ``Transform`` instead of ``Lookup`` it means we are able to chain
further lookups afterwards. So further lookups afterwards. So
``Experiment.objects.filter(change__abs__lt=27)`` will generate the following ``Experiment.objects.filter(change__abs__lt=27)`` will generate the following
SQL:: SQL:
.. code-block:: sql
SELECT ... WHERE ABS("experiments"."change") < 27 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``. ``change__abs=27`` as ``change__abs__exact=27``.
This also allows the result to be used in ``ORDER BY`` and ``DISTINCT ON`` 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 SELECT ... ORDER BY ABS("experiments"."change") ASC
And on databases that support distinct on fields (such as PostgreSQL), 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") 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``). ``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 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 SELECT .. WHERE "experiments"."change" < 27 AND "experiments"."change" > -27
@ -253,7 +265,9 @@ Next, let's register it::
TextField.register_lookup(UpperCase) TextField.register_lookup(UpperCase)
Now, the queryset ``Author.objects.filter(name__upper="doe")`` will generate a case 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') SELECT ... WHERE UPPER("author"."name") = UPPER('doe')

View File

@ -1273,7 +1273,9 @@ subclass::
word must be in at least one of ``search_fields``. For example, if 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 ``search_fields`` is set to ``['first_name', 'last_name']`` and a user
searches for ``john lennon``, Django will do the equivalent of this SQL 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%') WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%') AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')

View File

@ -445,11 +445,15 @@ Geometry example::
# the intersection pattern (the pattern here is for 'contains'). # the intersection pattern (the pattern here is for 'contains').
Zipcode.objects.filter(poly__relate=(geom, 'T*T***FF*')) 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*') 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*') 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(poly__relate=(rast, 1, 'T*T***FF*'))
Zipcode.objects.filter(rast__2__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(poly, ST_Polygon(rast, 1), 'T*T***FF*')
SELECT ... WHERE ST_Relate(ST_Polygon(rast, 2), 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')) Zipcode.objects.filter(poly__relate=(geom, 'anyinteract'))
Oracle SQL equivalent:: Oracle SQL equivalent:
.. code-block:: sql
SELECT ... WHERE SDO_RELATE(poly, geom, 'anyinteract') SELECT ... WHERE SDO_RELATE(poly, geom, 'anyinteract')
@ -552,7 +560,9 @@ Example::
Zipcode.objects.filter(poly__left=geom) Zipcode.objects.filter(poly__left=geom)
PostGIS equivalent:: PostGIS equivalent:
.. code-block:: sql
SELECT ... WHERE poly << geom SELECT ... WHERE poly << geom
@ -571,7 +581,9 @@ Example::
Zipcode.objects.filter(poly__right=geom) Zipcode.objects.filter(poly__right=geom)
PostGIS equivalent:: PostGIS equivalent:
.. code-block:: sql
SELECT ... WHERE poly >> geom SELECT ... WHERE poly >> geom
@ -590,7 +602,9 @@ Example::
Zipcode.objects.filter(poly__overlaps_left=geom) Zipcode.objects.filter(poly__overlaps_left=geom)
PostGIS equivalent:: PostGIS equivalent:
.. code-block:: sql
SELECT ... WHERE poly &< geom SELECT ... WHERE poly &< geom
@ -610,7 +624,9 @@ Example::
Zipcode.objects.filter(poly__overlaps_right=geom) Zipcode.objects.filter(poly__overlaps_right=geom)
PostGIS equivalent:: PostGIS equivalent:
.. code-block:: sql
SELECT ... WHERE poly &> geom SELECT ... WHERE poly &> geom
@ -629,7 +645,9 @@ Example::
Zipcode.objects.filter(poly__overlaps_above=geom) Zipcode.objects.filter(poly__overlaps_above=geom)
PostGIS equivalent:: PostGIS equivalent:
.. code-block:: sql
SELECT ... WHERE poly |&> geom SELECT ... WHERE poly |&> geom
@ -648,7 +666,9 @@ Example::
Zipcode.objects.filter(poly__overlaps_below=geom) Zipcode.objects.filter(poly__overlaps_below=geom)
PostGIS equivalent:: PostGIS equivalent:
.. code-block:: sql
SELECT ... WHERE poly &<| geom SELECT ... WHERE poly &<| geom
@ -667,7 +687,9 @@ Example::
Zipcode.objects.filter(poly__strictly_above=geom) Zipcode.objects.filter(poly__strictly_above=geom)
PostGIS equivalent:: PostGIS equivalent:
.. code-block:: sql
SELECT ... WHERE poly |>> geom SELECT ... WHERE poly |>> geom
@ -686,7 +708,9 @@ Example::
Zipcode.objects.filter(poly__strictly_below=geom) Zipcode.objects.filter(poly__strictly_below=geom)
PostGIS equivalent:: PostGIS equivalent:
.. code-block:: sql
SELECT ... WHERE poly <<| geom SELECT ... WHERE poly <<| geom

View File

@ -262,7 +262,9 @@ or they can be used to build a library of database functions::
queryset.annotate(field_lower=Lower('field')) queryset.annotate(field_lower=Lower('field'))
But both cases will result in a queryset where each model is annotated with an 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 SELECT
... ...

View File

@ -195,7 +195,9 @@ AND whose ``headline`` is "Hello"::
Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='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 ... SELECT ...
WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello') 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') 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 ... SELECT ...
WHERE NOT pub_date > '2005-1-3' WHERE NOT pub_date > '2005-1-3'
@ -1308,9 +1312,11 @@ generated by a ``QuerySet``.
``params`` in order to protect against SQL injection attacks. ``params`` in order to protect against SQL injection attacks.
You also must not quote placeholders in the SQL string. This example is 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 You can read more about how Django's :ref:`SQL injection protection
<sql-injection-protection>` works. <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. is greater than Jan. 1, 2006.
Django inserts the given SQL snippet directly into the ``SELECT`` Django inserts the given SQL snippet directly into the ``SELECT``
statement, so the resulting SQL of the above example would be something statement, so the resulting SQL of the above example would be something like:
like::
.. code-block:: sql
SELECT blog_entry.*, (pub_date > '2006-01-01') AS is_recent SELECT blog_entry.*, (pub_date > '2006-01-01') AS is_recent
FROM blog_entry; 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 In this particular case, we're exploiting the fact that the query will
already contain the ``blog_blog`` table in its ``FROM`` clause. 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 SELECT blog_blog.*, (SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id) AS entry_count
FROM blog_blog; 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'"]) 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') 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=14)
Entry.objects.get(id__exact=None) Entry.objects.get(id__exact=None)
SQL equivalents:: SQL equivalents:
.. code-block:: sql
SELECT ... WHERE id = 14; SELECT ... WHERE id = 14;
SELECT ... WHERE id IS NULL; SELECT ... WHERE id IS NULL;
@ -2650,7 +2663,9 @@ Example::
Blog.objects.get(name__iexact='beatles blog') Blog.objects.get(name__iexact='beatles blog')
Blog.objects.get(name__iexact=None) Blog.objects.get(name__iexact=None)
SQL equivalents:: SQL equivalents:
.. code-block:: sql
SELECT ... WHERE name ILIKE 'beatles blog'; SELECT ... WHERE name ILIKE 'beatles blog';
SELECT ... WHERE name IS NULL; SELECT ... WHERE name IS NULL;
@ -2675,7 +2690,9 @@ Example::
Entry.objects.get(headline__contains='Lennon') Entry.objects.get(headline__contains='Lennon')
SQL equivalent:: SQL equivalent:
.. code-block:: sql
SELECT ... WHERE headline LIKE '%Lennon%'; SELECT ... WHERE headline LIKE '%Lennon%';
@ -2700,7 +2717,9 @@ Example::
Entry.objects.get(headline__icontains='Lennon') Entry.objects.get(headline__icontains='Lennon')
SQL equivalent:: SQL equivalent:
.. code-block:: sql
SELECT ... WHERE headline ILIKE '%Lennon%'; SELECT ... WHERE headline ILIKE '%Lennon%';
@ -2722,7 +2741,9 @@ Examples::
Entry.objects.filter(id__in=[1, 3, 4]) Entry.objects.filter(id__in=[1, 3, 4])
Entry.objects.filter(headline__in='abc') Entry.objects.filter(headline__in='abc')
SQL equivalents:: SQL equivalents:
.. code-block:: sql
SELECT ... WHERE id IN (1, 3, 4); SELECT ... WHERE id IN (1, 3, 4);
SELECT ... WHERE headline IN ('a', 'b', 'c'); 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') inner_qs = Blog.objects.filter(name__contains='Cheddar')
entries = Entry.objects.filter(blog__in=inner_qs) 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%') SELECT ... WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE '%Cheddar%')
@ -2782,7 +2805,9 @@ Example::
Entry.objects.filter(id__gt=4) Entry.objects.filter(id__gt=4)
SQL equivalent:: SQL equivalent:
.. code-block:: sql
SELECT ... WHERE id > 4; SELECT ... WHERE id > 4;
@ -2818,7 +2843,9 @@ Example::
Entry.objects.filter(headline__startswith='Lennon') Entry.objects.filter(headline__startswith='Lennon')
SQL equivalent:: SQL equivalent:
.. code-block:: sql
SELECT ... WHERE headline LIKE 'Lennon%'; SELECT ... WHERE headline LIKE 'Lennon%';
@ -2836,7 +2863,9 @@ Example::
Entry.objects.filter(headline__istartswith='Lennon') Entry.objects.filter(headline__istartswith='Lennon')
SQL equivalent:: SQL equivalent:
.. code-block:: sql
SELECT ... WHERE headline ILIKE 'Lennon%'; SELECT ... WHERE headline ILIKE 'Lennon%';
@ -2856,7 +2885,9 @@ Example::
Entry.objects.filter(headline__endswith='Lennon') Entry.objects.filter(headline__endswith='Lennon')
SQL equivalent:: SQL equivalent:
.. code-block:: sql
SELECT ... WHERE headline LIKE '%Lennon'; SELECT ... WHERE headline LIKE '%Lennon';
@ -2877,7 +2908,9 @@ Example::
Entry.objects.filter(headline__iendswith='Lennon') Entry.objects.filter(headline__iendswith='Lennon')
SQL equivalent:: SQL equivalent:
.. code-block:: sql
SELECT ... WHERE headline ILIKE '%Lennon' SELECT ... WHERE headline ILIKE '%Lennon'
@ -2900,7 +2933,9 @@ Example::
end_date = datetime.date(2005, 3, 31) end_date = datetime.date(2005, 3, 31)
Entry.objects.filter(pub_date__range=(start_date, end_date)) 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'; 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 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 day, because the bounds are interpreted as "0am on the given date". If
``pub_date`` was a ``DateTimeField``, the above expression would be turned ``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'; 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=2005)
Entry.objects.filter(pub_date__year__gte=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 BETWEEN '2005-01-01' AND '2005-12-31';
SELECT ... WHERE pub_date >= '2005-01-01'; 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=12)
Entry.objects.filter(pub_date__month__gte=6) 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) = '12';
SELECT ... WHERE EXTRACT('month' FROM pub_date) >= '6'; 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=3)
Entry.objects.filter(pub_date__day__gte=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';
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(time__hour=5)
Event.objects.filter(timestamp__hour__gte=12) 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 timestamp) = '23';
SELECT ... WHERE EXTRACT('hour' FROM time) = '5'; SELECT ... WHERE EXTRACT('hour' FROM time) = '5';
@ -3156,7 +3201,9 @@ Example::
Event.objects.filter(time__minute=46) Event.objects.filter(time__minute=46)
Event.objects.filter(timestamp__minute__gte=29) 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 timestamp) = '29';
SELECT ... WHERE EXTRACT('minute' FROM time) = '46'; SELECT ... WHERE EXTRACT('minute' FROM time) = '46';
@ -3181,7 +3228,9 @@ Example::
Event.objects.filter(time__second=2) Event.objects.filter(time__second=2)
Event.objects.filter(timestamp__second__gte=31) 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 timestamp) = '31';
SELECT ... WHERE EXTRACT('second' FROM time) = '2'; SELECT ... WHERE EXTRACT('second' FROM time) = '2';
@ -3204,7 +3253,9 @@ Example::
Entry.objects.filter(pub_date__isnull=True) Entry.objects.filter(pub_date__isnull=True)
SQL equivalent:: SQL equivalent:
.. code-block:: sql
SELECT ... WHERE pub_date IS NULL; SELECT ... WHERE pub_date IS NULL;
@ -3224,7 +3275,9 @@ Example::
Entry.objects.get(title__regex=r'^(An?|The) +') Entry.objects.get(title__regex=r'^(An?|The) +')
SQL equivalents:: SQL equivalents:
.. code-block:: sql
SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL
@ -3248,7 +3301,9 @@ Example::
Entry.objects.get(title__iregex=r'^(an?|the) +') Entry.objects.get(title__iregex=r'^(an?|the) +')
SQL equivalents:: SQL equivalents:
.. code-block:: sql
SELECT ... WHERE title REGEXP '^(an?|the) +'; -- MySQL SELECT ... WHERE title REGEXP '^(an?|the) +'; -- MySQL

View File

@ -840,7 +840,9 @@ together. For example::
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)) 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%' SELECT * from polls WHERE question LIKE 'Who%'
AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06') AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')