forked from django/django
/
q-objects.txt
196 lines (140 loc) · 7.93 KB
/
q-objects.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
=========
Q objects
=========
.. currentmodule:: django.db.models
.. class:: Q(lookup_keyword_arguments)
A Q object is an object used to encapsulate a set of conditions which may be
used to query or filter a set of model objects.
In plain language these conditions might take the form "cars that are blue and
made after the year 1998" or "employees in the shipping department who are full
time or who have worked at the company for more than 10 years", etc.
The condition is composed from a set of field lookups keyword arguments as
specified for QuerySet methods::
from django.db.models import Q
my_condition = Q(color='blue', year_produced__gt=1998)
Q objects, once composed, can be used to generate QuerySets containing objects
(model instances) that match the condition, and can also be used to test
whether a given instance matches the condition. The same Q object can generally
be used in both capacities.
To query the database for cars matching the condition::
cars = Car.objects.filter(my_condition)
In the case where you already have an instance in hand, and you want to test
whether it matches the specified condition, you pass it to the
:meth:`Q.matches()` method::
if my_condition.matches(me_car_object):
print "we have a recent blue car"
``Q`` objects can be combined using the ``&`` and ``|`` operators. When an
operator is used on two ``Q`` objects, it yields a new ``Q`` object.
You can compose statements of arbitrary complexity by combining ``Q`` objects
with the ``&`` and ``|`` operators and use parenthetical grouping. Also, ``Q``
objects can be negated using the ``~`` operator, allowing for combined lookups
that combine both a normal query and a negated (``NOT``) query::
Q(question__startswith='Who') | ~Q(pub_date__year=2005)
Using Q objects with QuerySets
------------------------------
Each QuerySet lookup function that takes keyword-arguments
(e.g. :meth:`~django.db.models.query.QuerySet.filter`,
:meth:`~django.db.models.query.QuerySet.exclude`,
:meth:`~django.db.models.query.QuerySet.get`) can also be passed one or more
``Q`` objects as positional (not-named) arguments.
When Q objects are used with QuerySets, the condition they represent is
ultimately converted to SQL as appropriate for the database backend in use.
For example, this ``Q`` object encapsulates a single ``LIKE`` query::
from django.db.models import Q
Q(question__startswith='What')
When complex compound Q objects are used (those created with ``&`` or ``|``)
the logic is likewise represented in the resulting SQL.
For example, this statement yields a single ``Q`` object that represents the
"OR" of two ``"question__startswith"`` queries::
Q(question__startswith='Who') | Q(question__startswith='What')
This is equivalent to the following SQL ``WHERE`` clause::
WHERE question LIKE 'Who%' OR question LIKE 'What%'
If you provide multiple ``Q`` object arguments to a lookup function, the
arguments will be "AND"ed together. For example::
Poll.objects.get(
Q(question__startswith='Who'),
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)
... roughly translates into the SQL::
SELECT * from polls WHERE question LIKE 'Who%'
AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')
Lookup functions can mix the use of ``Q`` objects and keyword arguments. All
arguments provided to a lookup function (be they keyword arguments or ``Q``
objects) are "AND"ed together. However, if a ``Q`` object is provided, it must
precede the definition of any keyword arguments. For example::
Poll.objects.get(
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
question__startswith='Who')
... would be a valid query, equivalent to the previous example; but::
# INVALID QUERY
Poll.objects.get(
question__startswith='Who',
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))
... would not be valid.
.. seealso::
The `OR lookups examples`_ in the Django unit tests show some possible uses
of ``Q``.
.. _OR lookups examples: https://github.com/django/django/blob/master/tests/modeltests/or_lookups/tests.py
Using Q objects to test whether objects match a condition
---------------------------------------------------------
.. versionadded:: 1.5
There may be times when you already have a model object in hand and want to
know if it matches some defined condition. This may be a model from a QuerySet,
or a newly created model instance not yet saved to the database. Q objects can
be used to test whether that object matches the condition defined by the
Q object. Unlike Q objects used with QuerySet methods - a Q object can define
lookups on any attribute of a model, not just those that define database
fields.
.. method:: Q.matches(instance, [manager=None])
Returns ``True`` or ``False`` based on whether the instance matches the
condition specified by the Q object. If an object specifies multiple
managers, a specific manager can be specified, otherwise the default
manager is used. The need to specify a specific manager is uncommon - see
details on alternate managers below.
.. note::
When negating a Q object with the ``~`` operator, a new Q object is
returned, not negated in place. Because of operator precedence, this won't
work as expected: ``~my_q.matches(some_instance)`` as the match is
evaluated before the bitwise operator ``~``. Instead, use Python's ``not``
logical operator directly with the result of matches: ``not
my_q.matches(some_instance)``.
.. admonition:: Choose the right tool
When to use Q objects to test against some set of objects instead of
issuing a separate query to the database will depend on a number of
factors, including the number of different conditions you are testing, the
number of objects to be tested, and whether a QuerySet may already be
evaluated. Profiling and architectural necessity will be your best guides
in making the right choice.
(https://docs.djangoproject.com/en/dev/ref/models/querysets/#when-querysets-are-evaluated)
Match Compiling and alternate managers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. note::
This section covers API details that aren't commonly used.
Testing whether an instance matches a condition requires evaluating the lookups
in the context of the Model and Manager classes associated with that instance.
This information is not necessarily required or available at the time the
Q object is created. The first call to a Q object's ``matches`` method verifies
that the lookups are valid, and traverses any related objects, storing this
information for subsequent matches.
The manager provides information about supported lookup types. For example the
contrib.gis GeoManager provides details about the geographic specific lookup
types.
Like regex expressions, there may be times when there is some optimization to
precompiling the lookup evaluation. This requires information about the manager
at that time.
.. method:: Q.match_compile(manager)
The ``match_compile`` method will return a compiled matcher object with any
Model class and Manager specific information already evaluated. This
matcher object then has a ``matches`` method that mirrors the method
documented above (and in fact is what gets called privately in Q.matches)
If a precompiled matcher is called with an object that uses a different manager
than was specified at compile time, a ValueError is raised.
If a model has multiple managers, where these would result in different lookup
evaluations, the specific manager can be specified as an optional keyword
argument to ``Q.matches``
If, after the first call to ``Q.matches``, a subsequent call is made with an
instance using a different manager, the Q object recompiles it's internal
matcher object using the manager of the current instance. This means that if
you want to use the same Q object to match a variety different classes of model
objects, it would be more efficient to test all of one type, then all of
another etc.