“Django/docs/2.2.x/ref/models/querysets”的版本间差异

来自菜鸟教程
Django/docs/2.2.x/ref/models/querysets
跳转至:导航、​搜索
(autoload)
 
(Page commit)
 
第1行: 第1行:
 +
{{DISPLAYTITLE:QuerySet API 参考 — Django 文档}}
 
<div id="queryset-api-reference" class="section">
 
<div id="queryset-api-reference" class="section">
  
= <code>QuerySet</code> API reference =
+
= QuerySet API 参考 =
  
该文档描述了 <code>QuerySet</code> API 的细节。它是建立在 [[../../../topics/db/models|<span class="doc">模型</span>]] 和 [[../../../topics/db/queries|<span class="doc">数据库查询</span>]] 指南的材料基础上的,因此,在阅读这篇文档之前,您可能需要阅读和理解这些文档。
+
本文档描述了 <code>QuerySet</code> API 的详细信息。 它建立在 [[../../../topics/db/models|模型]] 和 [[../../../topics/db/queries|数据库查询]] 指南中提供的材料之上,因此您可能希望在阅读本文之前先阅读并理解这些文档。
  
在整篇参考中,我们将使用 [[../../../topics/db/queries|<span class="doc">数据库查询指南</span>]] 中的 [[../../../topics/db/queries#queryset-model-example|<span class="std std-ref">Weblog 示例模型</span>]] 。
+
在本参考文献中,我们将使用 [[../../../topics/db/queries|数据库查询指南]] 中介绍的 [[../../../topics/db/queries#queryset-model-example|示例网络日志模型]] 。
  
 
<div id="when-querysets-are-evaluated" class="section">
 
<div id="when-querysets-are-evaluated" class="section">
  
 
<span id="id1"></span>
 
<span id="id1"></span>
== When <code>QuerySet</code>s are evaluated ==
+
== 当评估 QuerySets 时 ==
  
Internally, a <code>QuerySet</code> can be constructed, filtered, sliced, and generally
+
在内部,<code>QuerySet</code> 可以被构造、过滤、切片,并且通常在不实际访问数据库的情况下传递。 在您执行某些操作来评估查询集之前,实际上不会发生数据库活动。
passed around without actually hitting the database. No database activity
 
actually occurs until you do something to evaluate the queryset.
 
  
You can evaluate a <code>QuerySet</code> in the following ways:
+
您可以通过以下方式评估 <code>QuerySet</code>
  
 
<ul>
 
<ul>
<li><p>'''Iteration.''' A <code>QuerySet</code> is iterable, and it executes its database
+
<li><p>'''Iteration.''' <code>QuerySet</code> 是可迭代的,它会在您第一次对其进行迭代时执行其数据库查询。 例如,这将打印数据库中所有条目的标题:</p>
query the first time you iterate over it. For example, this will print
 
the headline of all entries in the database:</p>
 
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>for e in Entry.objects.all():
+
<syntaxhighlight lang="python">for e in Entry.objects.all():
     print(e.headline)</pre>
+
     print(e.headline)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>Note: Don't use this if all you want to do is determine if at least one
+
<p>注意:如果您只想确定是否存在至少一个结果,请不要使用此选项。 使用 [[#django.db.models.query.QuerySet.exists|exists()]] 效率更高。</p></li>
result exists. It's more efficient to use [[#django.db.models.query.QuerySet.exists|<code>exists()</code>]].</p></li>
+
<li><p>'''切片。''' [[../../../topics/db/queries#limiting-querysets|Limiting QuerySets]] 中所述,可以使用 Python 的数组切片语法对 <code>QuerySet</code> 进行切片。 切片一个未赋值的 <code>QuerySet</code> 通常会返回另一个未赋值的 <code>QuerySet</code>,但如果使用切片语法的“step”参数,Django 将执行数据库查询,并返回一个列表。 对已求值的 <code>QuerySet</code> 进行切片也会返回一个列表。</p>
<li><p>'''Slicing.''' As explained in [[../../../topics/db/queries#limiting-querysets|<span class="std std-ref">限制 QuerySet 条目数</span>]], a <code>QuerySet</code> can
+
<p>另请注意,即使切片未计算的 <code>QuerySet</code> 返回另一个未计算的 <code>QuerySet</code>,也不允许进一步修改(例如,添加更多过滤器或修改排序),因为这不能很好地转换为 SQL它也不会有明确的含义。</p></li>
be sliced, using Python's array-slicing syntax. Slicing an unevaluated
+
<li><p>'''Pickling/Caching.''' [[#pickling-querysets|pickling QuerySets]] 时所涉及的详细信息,请参阅以下部分。 就本节而言,重要的是从数据库中读取结果。</p></li>
<code>QuerySet</code> usually returns another unevaluated <code>QuerySet</code>, but Django
+
<li><p>'''repr().''' 当您调用 <code>repr()</code> 时,会评估 <code>QuerySet</code>。 这是为了方便 Python 交互式解释器,因此您可以在交互式使用 API 时立即看到结果。</p></li>
will execute the database query if you use the &quot;step&quot; parameter of slice
+
<li><p>'''len().''' 当您调用 <code>len()</code> 时,会评估 <code>QuerySet</code>。 正如您所料,这将返回结果列表的长度。</p>
syntax, and will return a list. Slicing a <code>QuerySet</code> that has been
+
<p>注意:如果您只需要确定集合中的记录数(而不需要实际对象),使用 SQL <code>SELECT COUNT(*)</code> 在数据库级别处理计数会更有效。 正是出于这个原因,Django 提供了一个 [[#django.db.models.query.QuerySet.count|count()]] 方法。</p></li>
evaluated also returns a list.</p>
+
<li><p>'''list().''' 通过调用 <code>list()</code> 强制评估 <code>QuerySet</code>。 例如:</p>
<p>Also note that even though slicing an unevaluated <code>QuerySet</code> returns
 
another unevaluated <code>QuerySet</code>, modifying it further (e.g., adding
 
more filters, or modifying ordering) is not allowed, since that does not
 
translate well into SQL and it would not have a clear meaning either.</p></li>
 
<li><p>'''Pickling/Caching.''' See the following section for details of what
 
is involved when [[#pickling-querysets|pickling QuerySets]]. The important thing for the
 
purposes of this section is that the results are read from the database.</p></li>
 
<li><p>'''repr().''' A <code>QuerySet</code> is evaluated when you call <code>repr()</code> on it.
 
This is for convenience in the Python interactive interpreter, so you can
 
immediately see your results when using the API interactively.</p></li>
 
<li><p>'''len().''' A <code>QuerySet</code> is evaluated when you call <code>len()</code> on it.
 
This, as you might expect, returns the length of the result list.</p>
 
<p>Note: If you only need to determine the number of records in the set (and
 
don't need the actual objects), it's much more efficient to handle a count
 
at the database level using SQL's <code>SELECT COUNT(*)</code>. Django provides a
 
[[#django.db.models.query.QuerySet.count|<code>count()</code>]] method for precisely this reason.</p></li>
 
<li><p>'''list().''' Force evaluation of a <code>QuerySet</code> by calling <code>list()</code> on
 
it. For example:</p>
 
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>entry_list = list(Entry.objects.all())</pre>
+
<syntaxhighlight lang="python">entry_list = list(Entry.objects.all())</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div></li>
 
</div></li>
<li><p>'''bool().''' Testing a <code>QuerySet</code> in a boolean context, such as using
+
<li><p>'''bool().''' 在布尔上下文中测试 <code>QuerySet</code>,例如使用 <code>bool()</code><code>or</code><code>and</code> <code>if</code> 语句,将导致执行查询。 如果至少有一个结果,则<code>QuerySet</code><code>True</code>,否则为<code>False</code>。 例如:</p>
<code>bool()</code>, <code>or</code>, <code>and</code> or an <code>if</code> statement, will cause the query
 
to be executed. If there is at least one result, the <code>QuerySet</code> is
 
<code>True</code>, otherwise <code>False</code>. For example:</p>
 
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>if Entry.objects.filter(headline=&quot;Test&quot;):
+
<syntaxhighlight lang="python">if Entry.objects.filter(headline="Test"):
   print(&quot;There is at least one Entry with the headline Test&quot;)</pre>
+
   print("There is at least one Entry with the headline Test")</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>Note: If you only want to determine if at least one result exists (and don't
+
<p>注意:如果您只想确定是否至少存在一个结果(并且不需要实际对象),则使用 [[#django.db.models.query.QuerySet.exists|exists()]] 更有效。</p></li></ul>
need the actual objects), it's more efficient to use [[#django.db.models.query.QuerySet.exists|<code>exists()</code>]].</p></li></ul>
 
  
 
<div id="pickling-querysets" class="section">
 
<div id="pickling-querysets" class="section">
  
 
<span id="id2"></span>
 
<span id="id2"></span>
=== Pickling <code>QuerySet</code>s ===
+
=== 酸洗 QuerySets ===
  
If you <code>pickle</code> a <code>QuerySet</code>, this will force all the results to be loaded
+
如果你 <code>pickle</code> a <code>QuerySet</code>,这将强制所有结果在酸洗之前加载到内存中。 酸洗通常用作缓存的前兆,当重新加载缓存的查询集时,您希望结果已经存在并可供使用(从数据库中读取可能需要一些时间,违背了缓存的目的)。 这意味着当你 unpickle 一个 <code>QuerySet</code> 时,它包含它被pickle 时的结果,而不是当前在数据库中的结果。
into memory prior to pickling. Pickling is usually used as a precursor to
 
caching and when the cached queryset is reloaded, you want the results to
 
already be present and ready for use (reading from the database can take some
 
time, defeating the purpose of caching). This means that when you unpickle a
 
<code>QuerySet</code>, it contains the results at the moment it was pickled, rather
 
than the results that are currently in the database.
 
  
If you only want to pickle the necessary information to recreate the
+
如果您只想在稍后从数据库中腌制必要的信息以重新创建 <code>QuerySet</code>,请腌制 <code>QuerySet</code> <code>query</code> 属性。 然后,您可以使用如下代码重新创建原始 <code>QuerySet</code>(不加载任何结果):
<code>QuerySet</code> from the database at a later time, pickle the <code>query</code> attribute
 
of the <code>QuerySet</code>. You can then recreate the original <code>QuerySet</code> (without
 
any results loaded) using some code like this:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第106行: 第72行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; import pickle
+
<syntaxhighlight lang="python">>>> import pickle
&gt;&gt;&gt; query = pickle.loads(s)    # Assuming 's' is the pickled string.
+
>>> query = pickle.loads(s)    # Assuming 's' is the pickled string.
&gt;&gt;&gt; qs = MyModel.objects.all()
+
>>> qs = MyModel.objects.all()
&gt;&gt;&gt; qs.query = query            # Restore the original 'query'.</pre>
+
>>> qs.query = query            # Restore the original 'query'.</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The <code>query</code> attribute is an opaque object. It represents the internals of
+
<code>query</code> 属性是一个不透明的对象。 它代表查询构造的内部结构,而不是公共 API 的一部分。 但是,按照此处所述对属性的内容进行pickle 和unpickle 是安全的(并且完全受支持)。
the query construction and is not part of the public API. However, it is safe
 
(and fully supported) to pickle and unpickle the attribute's contents as
 
described here.
 
  
 
<div class="admonition-you-can-t-share-pickles-between-versions admonition">
 
<div class="admonition-you-can-t-share-pickles-between-versions admonition">
  
You can't share pickles between versions
+
您不能在版本之间共享泡菜
  
Pickles of <code>QuerySets</code> are only valid for the version of Django that
+
<code>QuerySets</code> 的泡菜仅对用于生成它们的 Django 版本有效。 如果您使用 Django 版本 N 生成 pickle,则无法保证使用 Django N+1 版本可以读取 pickle。 不应将泡菜用作长期存档策略的一部分。
was used to generate them. If you generate a pickle using Django
 
version N, there is no guarantee that pickle will be readable with
 
Django version N+1. Pickles should not be used as part of a long-term
 
archival strategy.
 
  
Since pickle compatibility errors can be difficult to diagnose, such as
+
由于pickle 兼容性错误可能难以诊断,例如静默损坏的对象,因此当您尝试在与pickle 版本不同的Django 版本中对查询集进行unpickle 时,会引发<code>RuntimeWarning</code>
silently corrupted objects, a <code>RuntimeWarning</code> is raised when you try to
 
unpickle a queryset in a Django version that is different than the one in
 
which it was pickled.
 
  
  
第143行: 第99行:
  
 
<span id="id3"></span>
 
<span id="id3"></span>
== <code>QuerySet</code> API ==
+
== QuerySet API ==
  
Here's the formal declaration of a <code>QuerySet</code>:
+
这是 <code>QuerySet</code> 的正式声明:
  
 
<dl>
 
<dl>
<dt>''class'' <code>QuerySet</code><span class="sig-paren">(</span>''<span class="n">model</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">query</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">using</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">hints</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span>[[../../_modules/django/db/models/query.html#QuerySet|<span class="viewcode-link">[源代码]</span>]]</dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">QuerySet</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">model</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">query</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">using</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">hints</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Usually when you'll interact with a <code>QuerySet</code> you'll use it by
+
<dd><p>通常,当您与 <code>QuerySet</code> 交互时,您会通过 [[../../../topics/db/queries#chaining-filters|链接过滤器]] 来使用它。 为了完成这项工作,大多数 <code>QuerySet</code> 方法返回新的查询集。 本节稍后将详细介绍这些方法。</p>
[[../../../topics/db/queries#chaining-filters|<span class="std std-ref">chaining filters</span>]]. To make this work, most
+
<p><code>QuerySet</code> 类有两个可用于自省的公共属性:</p>
<code>QuerySet</code> methods return new querysets. These methods are covered in
 
detail later in this section.</p>
 
<p>The <code>QuerySet</code> class has two public attributes you can use for
 
introspection:</p>
 
 
<dl>
 
<dl>
<dt><code>ordered</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">ordered</span></span></dt>
<dd><p><code>True</code> if the <code>QuerySet</code> is ordered i.e. has an
+
<dd><p><code>True</code> 如果订购了 <code>QuerySet</code> — 即 在模型上有一个 [[#django.db.models.query.QuerySet.order_by|order_by()]] 子句或默认排序。 <code>False</code> 否则。</p></dd></dl>
[[#django.db.models.query.QuerySet.order_by|<code>order_by()</code>]] clause or a default ordering on the model.
 
<code>False</code> otherwise.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>db</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">db</span></span></dt>
<dd><p>The database that will be used if this query is executed now.</p></dd></dl>
+
<dd><p>如果现在执行这个查询,将使用的数据库。</p></dd></dl>
  
 
<div class="admonition note">
 
<div class="admonition note">
  
 
<p>注解</p>
 
<p>注解</p>
<p>The <code>query</code> parameter to [[#django.db.models.query.QuerySet|<code>QuerySet</code>]] exists so that specialized
+
<p>[[#django.db.models.query.QuerySet|QuerySet]] 的 <code>query</code> 参数存在以便专门的查询子类可以重建内部查询状态。 该参数的值是该查询状态的不透明表示,不是公共 API 的一部分。 简单地说:如果你需要问,你不需要使用它。</p>
query subclasses can reconstruct internal query state. The value of the
 
parameter is an opaque representation of that query state and is not
 
part of a public API. To put it simply: if you need to ask, you don't
 
need to use it.</p>
 
  
 
</div></dd></dl>
 
</div></dd></dl>
第178行: 第124行:
 
<div id="methods-that-return-new-querysets" class="section">
 
<div id="methods-that-return-new-querysets" class="section">
  
=== Methods that return new <code>QuerySet</code>s ===
+
=== 返回新 QuerySet 的方法 ===
  
Django provides a range of <code>QuerySet</code> refinement methods that modify either
+
Django 提供了一系列 <code>QuerySet</code> 细化方法,可以修改 <code>QuerySet</code> 返回的结果类型或其 SQL 查询的执行方式。
the types of results returned by the <code>QuerySet</code> or the way its SQL query is
 
executed.
 
  
 
<div id="filter" class="section">
 
<div id="filter" class="section">
  
==== <code>filter()</code> ====
+
==== filter() ====
  
; <code>filter</code><span class="sig-paren">(</span>''<span class="o">**</span><span class="n">kwargs</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">filter</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Returns a new <code>QuerySet</code> containing objects that match the given lookup
+
返回包含与给定查找参数匹配的对象的新 <code>QuerySet</code>
parameters.
 
  
The lookup parameters (<code>**kwargs</code>) should be in the format described in
+
查找参数 (<code>**kwargs</code>) 应采用以下 [[#id10|字段查找]] 中描述的格式。 多个参数通过底层 SQL 语句中的 <code>AND</code> 连接。
[[#id4|Field lookups]] below. Multiple parameters are joined via <code>AND</code> in the
 
underlying SQL statement.
 
  
If you need to execute more complex queries (for example, queries with <code>OR</code> statements),
+
如果您需要执行更复杂的查询(例如,使用 <code>OR</code> 语句的查询),您可以使用 [[#django.db.models.Q|Q 对象]]
you can use [[#django.db.models.Q|<code>Q objects</code>]].
 
  
  
第205行: 第145行:
 
<div id="exclude" class="section">
 
<div id="exclude" class="section">
  
==== <code>exclude()</code> ====
+
==== exclude() ====
  
; <code>exclude</code><span class="sig-paren">(</span>''<span class="o">**</span><span class="n">kwargs</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">exclude</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Returns a new <code>QuerySet</code> containing objects that do ''not'' match the given
+
返回一个新的 <code>QuerySet</code>,其中包含 '''' 不匹配给定查找参数的对象。
lookup parameters.
 
  
The lookup parameters (<code>**kwargs</code>) should be in the format described in
+
查找参数 (<code>**kwargs</code>) 应采用以下 [[#id10|字段查找]] 中描述的格式。 多个参数通过底层 SQL 语句中的 <code>AND</code> 连接起来,整个内容包含在一个 <code>NOT()</code> 中。
[[#id4|Field lookups]] below. Multiple parameters are joined via <code>AND</code> in the
 
underlying SQL statement, and the whole thing is enclosed in a <code>NOT()</code>.
 
  
This example excludes all entries whose <code>pub_date</code> is later than 2005-1-3
+
此示例排除 <code>pub_date</code> 晚于 2005-1-3 <code>headline</code> 为“Hello”的所有条目:
AND whose <code>headline</code> is &quot;Hello&quot;:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第224行: 第160行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello')</pre>
+
<syntaxhighlight lang="python">Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
In SQL terms, that evaluates to:
+
SQL 术语中,计算结果为:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第235行: 第171行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ...
+
<syntaxhighlight lang="python">SELECT ...
WHERE NOT (pub_date &gt; '2005-1-3' AND headline = 'Hello')</pre>
+
WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
This example excludes all entries whose <code>pub_date</code> is later than 2005-1-3
+
此示例排除 <code>pub_date</code> 晚于 2005-1-3 或标题为“您好”的所有条目:
OR whose headline is &quot;Hello&quot;:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第248行: 第183行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3)).exclude(headline='Hello')</pre>
+
<syntaxhighlight lang="python">Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3)).exclude(headline='Hello')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
In SQL terms, that evaluates to:
+
SQL 术语中,计算结果为:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第259行: 第194行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ...
+
<syntaxhighlight lang="python">SELECT ...
WHERE NOT pub_date &gt; '2005-1-3'
+
WHERE NOT pub_date > '2005-1-3'
AND NOT headline = 'Hello'</pre>
+
AND NOT headline = 'Hello'</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Note the second example is more restrictive.
+
请注意,第二个例子的限制性更强。
  
If you need to execute more complex queries (for example, queries with <code>OR</code> statements),
+
如果您需要执行更复杂的查询(例如,使用 <code>OR</code> 语句的查询),您可以使用 [[#django.db.models.Q|Q 对象]]
you can use [[#django.db.models.Q|<code>Q objects</code>]].
 
  
  
第275行: 第209行:
 
<div id="annotate" class="section">
 
<div id="annotate" class="section">
  
==== <code>annotate()</code> ====
+
==== annotate() ====
  
; <code>annotate</code><span class="sig-paren">(</span>''<span class="o">*</span><span class="n">args</span>'', ''<span class="o">**</span><span class="n">kwargs</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">annotate</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">args</span></span>'', ''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Annotates each object in the <code>QuerySet</code> with the provided list of [[../expressions|<span class="doc">query
+
使用提供的 [[../expressions|查询表达式]] 列表注释 <code>QuerySet</code> 中的每个对象。 表达式可以是一个简单的值、对模型(或任何相关模型)上的字段的引用,或者是对与模型中的对象相关的对象进行计算的聚合表达式(平均值、总和等)。 <code>QuerySet</code>
expressions</span>]]. An expression may be a simple value, a
 
reference to a field on the model (or any related models), or an aggregate
 
expression (averages, sums, etc.) that has been computed over the objects that
 
are related to the objects in the <code>QuerySet</code>.
 
  
Each argument to <code>annotate()</code> is an annotation that will be added
+
<code>annotate()</code> 的每个参数都是一个注释,将添加到返回的 <code>QuerySet</code> 中的每个对象。
to each object in the <code>QuerySet</code> that is returned.
 
  
The aggregation functions that are provided by Django are described
+
Django 提供的聚合函数在下面的 [[#id41|Aggregation Functions]] 中描述。
in [[#id5|Aggregation Functions]] below.
 
  
Annotations specified using keyword arguments will use the keyword as
+
使用关键字参数指定的注释将使用关键字作为注释的别名。 匿名参数将根据聚合函数的名称和正在聚合的模型字段为它们生成一个别名。 只有引用单个字段的聚合表达式才能是匿名参数。 其他所有内容都必须是关键字参数。
the alias for the annotation. Anonymous arguments will have an alias
 
generated for them based upon the name of the aggregate function and
 
the model field that is being aggregated. Only aggregate expressions
 
that reference a single field can be anonymous arguments. Everything
 
else must be a keyword argument.
 
  
For example, if you were manipulating a list of blogs, you may want
+
例如,如果您正在操作一个博客列表,您可能想要确定每个博客中已经创建了多少条目:
to determine how many entries have been made in each blog:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第306行: 第228行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; from django.db.models import Count
+
<syntaxhighlight lang="python">>>> from django.db.models import Count
&gt;&gt;&gt; q = Blog.objects.annotate(Count('entry'))
+
>>> q = Blog.objects.annotate(Count('entry'))
 
# The name of the first blog
 
# The name of the first blog
&gt;&gt;&gt; q[0].name
+
>>> q[0].name
 
'Blogasaurus'
 
'Blogasaurus'
 
# The number of entries on the first blog
 
# The number of entries on the first blog
&gt;&gt;&gt; q[0].entry__count
+
>>> q[0].entry__count
42</pre>
+
42</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The <code>Blog</code> model doesn't define an <code>entry__count</code> attribute by itself,
+
<code>Blog</code> 模型本身并没有定义 <code>entry__count</code> 属性,但是通过使用关键字参数指定聚合函数,您可以控制注解的名称:
but by using a keyword argument to specify the aggregate function, you can
 
control the name of the annotation:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第326行: 第246行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; q = Blog.objects.annotate(number_of_entries=Count('entry'))
+
<syntaxhighlight lang="python">>>> q = Blog.objects.annotate(number_of_entries=Count('entry'))
 
# The number of entries on the first blog, using the name provided
 
# The number of entries on the first blog, using the name provided
&gt;&gt;&gt; q[0].number_of_entries
+
>>> q[0].number_of_entries
42</pre>
+
42</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
For an in-depth discussion of aggregation, see [[../../../topics/db/aggregation|<span class="doc">the topic guide on
+
有关聚合的深入讨论,请参阅 [[../../../topics/db/aggregation|有关聚合的主题指南]]
Aggregation</span>]].
 
  
  
第341行: 第260行:
 
<div id="order-by" class="section">
 
<div id="order-by" class="section">
  
==== <code>order_by()</code> ====
+
==== order_by() ====
  
; <code>order_by</code><span class="sig-paren">(</span>''<span class="o">*</span><span class="n">fields</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">order_by</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">fields</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
By default, results returned by a <code>QuerySet</code> are ordered by the ordering
+
默认情况下,<code>QuerySet</code> 返回的结果按模型的 <code>Meta</code> 中的 <code>ordering</code> 选项给出的排序元组排序。 您可以使用 <code>order_by</code> 方法在每个 <code>QuerySet</code> 的基础上覆盖它。
tuple given by the <code>ordering</code> option in the model's <code>Meta</code>. You can
 
override this on a per-<code>QuerySet</code> basis by using the <code>order_by</code> method.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第356行: 第273行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline')</pre>
+
<syntaxhighlight lang="python">Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The result above will be ordered by <code>pub_date</code> descending, then by
+
上面的结果将按 <code>pub_date</code> 降序排列,然后按 <code>headline</code> 升序排列。 <code>&quot;-pub_date&quot;</code>前面的负号表示''降序''。 升序是隐含的。 要随机排序,请使用 <code>&quot;?&quot;</code>,如下所示:
<code>headline</code> ascending. The negative sign in front of <code>&quot;-pub_date&quot;</code> indicates
 
''descending'' order. Ascending order is implied. To order randomly, use <code>&quot;?&quot;</code>,
 
like so:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第370行: 第284行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.order_by('?')</pre>
+
<syntaxhighlight lang="python">Entry.objects.order_by('?')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Note: <code>order_by('?')</code> queries may be expensive and slow, depending on the
+
注意:<code>order_by('?')</code> 查询可能既昂贵又缓慢,具体取决于您使用的数据库后端。
database backend you're using.
 
  
To order by a field in a different model, use the same syntax as when you are
+
要按不同模型中的字段排序,请使用与跨模型关系查询时相同的语法。 即,字段名称,后跟双下划线 (<code>__</code>),后跟新模型中的字段名称,依此类推,适用于您想要加入的模型。 例如:
querying across model relations. That is, the name of the field, followed by a
 
double underscore (<code>__</code>), followed by the name of the field in the new model,
 
and so on for as many models as you want to join. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第387行: 第297行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.order_by('blog__name', 'headline')</pre>
+
<syntaxhighlight lang="python">Entry.objects.order_by('blog__name', 'headline')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
If you try to order by a field that is a relation to another model, Django will
+
如果您尝试按与另一个模型相关的字段排序,Django 将使用相关模型的默认排序,或者如果未指定 [[../options#django.db.models.Options|Meta.ordering]],则按相关模型的主键排序。 例如,由于 <code>Blog</code> 模型没有指定默认排序:
use the default ordering on the related model, or order by the related model's
 
primary key if there is no [[../options#django.db.models.Options|<code>Meta.ordering</code>]] specified. For example, since the <code>Blog</code>
 
model has no default ordering specified:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第401行: 第308行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.order_by('blog')</pre>
+
<syntaxhighlight lang="python">Entry.objects.order_by('blog')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
...is identical to:
+
……等同于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第412行: 第319行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.order_by('blog__id')</pre>
+
<syntaxhighlight lang="python">Entry.objects.order_by('blog__id')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
If <code>Blog</code> had <code>ordering = ['name']</code>, then the first queryset would be
+
如果 <code>Blog</code> <code>ordering = ['name']</code>,那么第一个查询集将等同于:
identical to:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第424行: 第330行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.order_by('blog__name')</pre>
+
<syntaxhighlight lang="python">Entry.objects.order_by('blog__name')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
You can also order by [[../expressions|<span class="doc">query expressions</span>]] by
+
您还可以通过在表达式上调用 [[../expressions#django.db.models.Expression|asc()]] [[../expressions#django.db.models.Expression|desc()]] 来按 [[../expressions|查询表达式]] 排序:
calling [[../expressions#django.db.models.Expression|<code>asc()</code>]] or [[../expressions#django.db.models.Expression|<code>desc()</code>]] on the
 
expression:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第437行: 第341行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.order_by(Coalesce('summary', 'headline').desc())</pre>
+
<syntaxhighlight lang="python">Entry.objects.order_by(Coalesce('summary', 'headline').desc())</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
[[../expressions#django.db.models.Expression|<code>asc()</code>]] and [[../expressions#django.db.models.Expression|<code>desc()</code>]] have arguments
+
[[../expressions#django.db.models.Expression|asc()]] [[../expressions#django.db.models.Expression|desc()]] 具有控制空值排序方式的参数(<code>nulls_first</code> <code>nulls_last</code>)。
(<code>nulls_first</code> and <code>nulls_last</code>) that control how null values are sorted.
 
  
Be cautious when ordering by fields in related models if you are also using
+
如果您还使用 [[#django.db.models.query.QuerySet.distinct|distinct()]],则在按相关模型中的字段排序时要小心。 有关相关模型排序如何改变预期结果的说明,请参阅 [[#django.db.models.query.QuerySet.distinct|distinct()]] 中的注释。
[[#django.db.models.query.QuerySet.distinct|<code>distinct()</code>]]. See the note in [[#django.db.models.query.QuerySet.distinct|<code>distinct()</code>]] for an explanation of how
 
related model ordering can change the expected results.
 
  
 
<div class="admonition note">
 
<div class="admonition note">
第453行: 第354行:
 
注解
 
注解
  
It is permissible to specify a multi-valued field to order the results by
+
允许指定多值字段以对结果进行排序(例如,[[../fields#django.db.models|ManyToManyField]] 字段,或 [[../fields#django.db.models|ForeignKey]] 字段的反向关系)。
(for example, a [[../fields#django.db.models|<code>ManyToManyField</code>]] field, or the
 
reverse relation of a [[../fields#django.db.models|<code>ForeignKey</code>]] field).
 
  
Consider this case:
+
考虑这个案例:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第463行: 第362行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>class Event(Model):
+
<syntaxhighlight lang="python">class Event(Model):
 
   parent = models.ForeignKey(
 
   parent = models.ForeignKey(
 
       'self',
 
       'self',
第471行: 第370行:
 
   date = models.DateField()
 
   date = models.DateField()
  
Event.objects.order_by('children__date')</pre>
+
Event.objects.order_by('children__date')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Here, there could potentially be multiple ordering data for each <code>Event</code>;
+
在这里,每个 <code>Event</code> 可能有多个排序数据; 每个带有多个 <code>children</code> <code>Event</code> 将多次返回到 <code>order_by()</code> 创建的新 <code>QuerySet</code> 中。 换句话说,在 <code>QuerySet</code> 上使用 <code>order_by()</code> 可能会返回比您开始时更多的项目 - 这可能既不符合预期也没有用。
each <code>Event</code> with multiple <code>children</code> will be returned multiple times
 
into the new <code>QuerySet</code> that <code>order_by()</code> creates. In other words,
 
using <code>order_by()</code> on the <code>QuerySet</code> could return more items than you
 
were working on to begin with - which is probably neither expected nor
 
useful.
 
  
Thus, take care when using multi-valued field to order the results. '''If'''
+
因此,在使用多值字段对结果进行排序时要小心。 '''如果'''您可以确定您订购的每件商品只有一个订购数据,那么这种方法应该不会出现问题。 如果没有,请确保结果符合您的预期。
you can be sure that there will only be one ordering piece of data for each
 
of the items you're ordering, this approach should not present problems. If
 
not, make sure the results are what you expect.
 
  
  
 
</div>
 
</div>
There's no way to specify whether ordering should be case sensitive. With
+
无法指定排序是否应区分大小写。 关于区分大小写,Django 会对结果进行排序,但您的数据库后端通常会对其进行排序。
respect to case-sensitivity, Django will order results however your database
 
backend normally orders them.
 
  
You can order by a field converted to lowercase with
+
您可以使用 [[../database-functions#django.db.models.functions|Lower]] 将字段转换为小写,这将实现大小写一致的排序:
[[../database-functions#django.db.models.functions|<code>Lower</code>]] which will achieve case-consistent
 
ordering:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第502行: 第389行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.order_by(Lower('headline').desc())</pre>
+
<syntaxhighlight lang="python">Entry.objects.order_by(Lower('headline').desc())</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
If you don't want any ordering to be applied to a query, not even the default
+
如果您不希望对查询应用任何排序,甚至不希望应用默认排序,请调用不带参数的 [[#django.db.models.query.QuerySet.order_by|order_by()]]
ordering, call [[#django.db.models.query.QuerySet.order_by|<code>order_by()</code>]] with no parameters.
 
  
You can tell if a query is ordered or not by checking the
+
您可以通过检查 [[#django.db.models.query.QuerySet.ordered|QuerySet.ordered]] 属性来判断查询是否已排序,如果 <code>QuerySet</code> 已以任何方式排序,则该属性将为 <code>True</code>
[[#django.db.models.query.QuerySet.ordered|<code>QuerySet.ordered</code>]] attribute, which will be <code>True</code> if the
 
<code>QuerySet</code> has been ordered in any way.
 
  
Each <code>order_by()</code> call will clear any previous ordering. For example, this
+
每个 <code>order_by()</code> 调用将清除任何先前的排序。 例如,此查询将按 <code>pub_date</code> 而不是 <code>headline</code> 排序:
query will be ordered by <code>pub_date</code> and not <code>headline</code>:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第521行: 第404行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.order_by('headline').order_by('pub_date')</pre>
+
<syntaxhighlight lang="python">Entry.objects.order_by('headline').order_by('pub_date')</syntaxhighlight>
  
 
</div>
 
</div>
第530行: 第413行:
 
警告
 
警告
  
Ordering is not a free operation. Each field you add to the ordering
+
订购不是免费的操作。 您添加到排序中的每个字段都会对您的数据库产生成本。 您添加的每个外键也将隐式包含其所有默认排序。
incurs a cost to your database. Each foreign key you add will
 
implicitly include all of its default orderings as well.
 
  
If a query doesn't have an ordering specified, results are returned from
+
如果查询未指定排序,则以未指定的顺序从数据库返回结果。 只有在按唯一标识结果中每个对象的一组字段进行排序时,才能保证特定的排序。 例如,如果 <code>name</code> 字段不是唯一的,按它排序并不能保证具有相同名称的对象总是以相同的顺序出现。
the database in an unspecified order. A particular ordering is guaranteed
 
only when ordering by a set of fields that uniquely identify each object in
 
the results. For example, if a <code>name</code> field isn't unique, ordering by it
 
won't guarantee objects with the same name always appear in the same order.
 
  
  
第548行: 第425行:
 
==== reverse() ====
 
==== reverse() ====
  
; <code>reverse</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">reverse</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
 
:  
 
:  
  
Use the <code>reverse()</code> method to reverse the order in which a queryset's
+
使用 <code>reverse()</code> 方法反转查询集元素的返回顺序。 再次调用 <code>reverse()</code> 会将排序恢复到正常方向。
elements are returned. Calling <code>reverse()</code> a second time restores the
 
ordering back to the normal direction.
 
  
To retrieve the &quot;last&quot; five items in a queryset, you could do this:
+
要检索查询集中的“最后”五个项目,您可以这样做:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第561行: 第436行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>my_queryset.reverse()[:5]</pre>
+
<syntaxhighlight lang="python">my_queryset.reverse()[:5]</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Note that this is not quite the same as slicing from the end of a sequence in
+
请注意,这与在 Python 中从序列末尾进行切片并不完全相同。 上面的例子将首先返回最后一项,然后是倒数第二项,依此类推。 如果我们有一个 Python 序列并查看 <code>seq[-5:]</code>,我们将首先看到倒数第五项。 Django 不支持这种访问模式(从末尾切片),因为在 SQL 中不可能有效地做到这一点。
Python. The above example will return the last item first, then the
 
penultimate item and so on. If we had a Python sequence and looked at
 
<code>seq[-5:]</code>, we would see the fifth-last item first. Django doesn't support
 
that mode of access (slicing from the end), because it's not possible to do it
 
efficiently in SQL.
 
  
Also, note that <code>reverse()</code> should generally only be called on a <code>QuerySet</code>
+
另外,请注意 <code>reverse()</code> 通常只应在具有定义排序的 <code>QuerySet</code> 上调用(例如,当查询定义默认排序的模型时,或使用 [[#django.db.models.query.QuerySet.order_by|order_by( )]])。 如果没有为给定的 <code>QuerySet</code> 定义这样的排序,则对其调用 <code>reverse()</code> 没有实际影响(排序在调用 <code>reverse()</code> 之前未定义,之后将保持未定义) .
which has a defined ordering (e.g., when querying against a model which defines
 
a default ordering, or when using [[#django.db.models.query.QuerySet.order_by|<code>order_by()</code>]]). If no such ordering is
 
defined for a given <code>QuerySet</code>, calling <code>reverse()</code> on it has no real
 
effect (the ordering was undefined prior to calling <code>reverse()</code>, and will
 
remain undefined afterward).
 
  
  
第584行: 第449行:
 
<div id="distinct" class="section">
 
<div id="distinct" class="section">
  
==== <code>distinct()</code> ====
+
==== distinct() ====
  
; <code>distinct</code><span class="sig-paren">(</span>''<span class="o">*</span><span class="n">fields</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">distinct</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">fields</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Returns a new <code>QuerySet</code> that uses <code>SELECT DISTINCT</code> in its SQL query. This
+
返回在其 SQL 查询中使用 <code>SELECT DISTINCT</code> 的新 <code>QuerySet</code>。 这消除了查询结果中的重复行。
eliminates duplicate rows from the query results.
 
  
By default, a <code>QuerySet</code> will not eliminate duplicate rows. In practice, this
+
默认情况下,<code>QuerySet</code> 不会消除重复行。 在实践中,这很少成为问题,因为像 <code>Blog.objects.all()</code> 这样的简单查询不会引入重复结果行的可能性。 但是,如果您的查询跨越多个表,则在评估 <code>QuerySet</code> 时可能会得到重复的结果。 那时你会使用 <code>distinct()</code>
is rarely a problem, because simple queries such as <code>Blog.objects.all()</code>
 
don't introduce the possibility of duplicate result rows. However, if your
 
query spans multiple tables, it's possible to get duplicate results when a
 
<code>QuerySet</code> is evaluated. That's when you'd use <code>distinct()</code>.
 
  
 
<div class="admonition note">
 
<div class="admonition note">
第602行: 第462行:
 
注解
 
注解
  
Any fields used in an [[#django.db.models.query.QuerySet.order_by|<code>order_by()</code>]] call are included in the SQL
+
[[#django.db.models.query.QuerySet.order_by|order_by()]] 调用中使用的任何字段都包含在 SQL <code>SELECT</code> 列中。 当与 <code>distinct()</code> 结合使用时,有时会导致意外结果。 如果您按相关模型中的字段排序,这些字段将被添加到选定的列中,否则它们可能会使重复的行看起来不同。 由于额外的列不会出现在返回的结果中(它们仅用于支持排序),因此有时看起来返回的是非不同的结果。
<code>SELECT</code> columns. This can sometimes lead to unexpected results when used
 
in conjunction with <code>distinct()</code>. If you order by fields from a related
 
model, those fields will be added to the selected columns and they may make
 
otherwise duplicate rows appear to be distinct. Since the extra columns
 
don't appear in the returned results (they are only there to support
 
ordering), it sometimes looks like non-distinct results are being returned.
 
  
Similarly, if you use a [[#django.db.models.query.QuerySet.values|<code>values()</code>]] query to restrict the columns
+
同样,如果您使用 [[#django.db.models.query.QuerySet.values|values()]] 查询来限制选择的列,则任何 [[#django.db.models.query.QuerySet.order_by|order_by()]](或默认模型排序)中使用的列仍将涉及并可能影响唯一性的结果。
selected, the columns used in any [[#django.db.models.query.QuerySet.order_by|<code>order_by()</code>]] (or default model
 
ordering) will still be involved and may affect uniqueness of the results.
 
  
The moral here is that if you are using <code>distinct()</code> be careful about
+
这里的寓意是,如果您使用 <code>distinct()</code>,请注意按相关型号排序。 同样,当一起使用 <code>distinct()</code> [[#django.db.models.query.QuerySet.values|values()]] 时,按不在 [[#django.db.models.query.QuerySet.values|values()]] 调用中的字段排序时要小心。
ordering by related models. Similarly, when using <code>distinct()</code> and
 
[[#django.db.models.query.QuerySet.values|<code>values()</code>]] together, be careful when ordering by fields not in the
 
[[#django.db.models.query.QuerySet.values|<code>values()</code>]] call.
 
  
  
 
</div>
 
</div>
On PostgreSQL only, you can pass positional arguments (<code>*fields</code>) in order to
+
仅在 PostgreSQL 上,您可以传递位置参数 (<code>*fields</code>) 以指定 <code>DISTINCT</code> 应适用的字段名称。 这将转换为 <code>SELECT DISTINCT ON</code> SQL 查询。 这就是不同之处。 对于正常的 <code>distinct()</code> 调用,数据库在确定哪些行不同时比较每行中的 ''each'' 字段。 对于具有指定字段名称的 <code>distinct()</code> 调用,数据库将仅比较指定的字段名称。
specify the names of fields to which the <code>DISTINCT</code> should apply. This
 
translates to a <code>SELECT DISTINCT ON</code> SQL query. Here's the difference. For a
 
normal <code>distinct()</code> call, the database compares ''each'' field in each row when
 
determining which rows are distinct. For a <code>distinct()</code> call with specified
 
field names, the database will only compare the specified field names.
 
  
 
<div class="admonition note">
 
<div class="admonition note">
第632行: 第476行:
 
注解
 
注解
  
When you specify field names, you ''must'' provide an <code>order_by()</code> in the
+
指定字段名称时,''必须''<code>QuerySet</code>中提供<code>order_by()</code><code>order_by()</code>中的字段必须以<code>distinct()</code>,顺序相同。
<code>QuerySet</code>, and the fields in <code>order_by()</code> must start with the fields in
 
<code>distinct()</code>, in the same order.
 
  
For example, <code>SELECT DISTINCT ON (a)</code> gives you the first row for each
+
例如,<code>SELECT DISTINCT ON (a)</code> 为您提供 <code>a</code> 列中每个值的第一行。 如果您不指定顺序,您将得到一些任意行。
value in column <code>a</code>. If you don't specify an order, you'll get some
 
arbitrary row.
 
  
  
 
</div>
 
</div>
Examples (those after the first will only work on PostgreSQL):
+
示例(第一个之后的仅适用于 PostgreSQL):
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第648行: 第488行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Author.objects.distinct()
+
<syntaxhighlight lang="python">>>> Author.objects.distinct()
 
[...]
 
[...]
  
&gt;&gt;&gt; Entry.objects.order_by('pub_date').distinct('pub_date')
+
>>> Entry.objects.order_by('pub_date').distinct('pub_date')
 
[...]
 
[...]
  
&gt;&gt;&gt; Entry.objects.order_by('blog').distinct('blog')
+
>>> Entry.objects.order_by('blog').distinct('blog')
 
[...]
 
[...]
  
&gt;&gt;&gt; Entry.objects.order_by('author', 'pub_date').distinct('author', 'pub_date')
+
>>> Entry.objects.order_by('author', 'pub_date').distinct('author', 'pub_date')
 
[...]
 
[...]
  
&gt;&gt;&gt; Entry.objects.order_by('blog__name', 'mod_date').distinct('blog__name', 'mod_date')
+
>>> Entry.objects.order_by('blog__name', 'mod_date').distinct('blog__name', 'mod_date')
 
[...]
 
[...]
  
&gt;&gt;&gt; Entry.objects.order_by('author', 'pub_date').distinct('author')
+
>>> Entry.objects.order_by('author', 'pub_date').distinct('author')
[...]</pre>
+
[...]</syntaxhighlight>
  
 
</div>
 
</div>
第673行: 第513行:
 
注解
 
注解
  
Keep in mind that [[#django.db.models.query.QuerySet.order_by|<code>order_by()</code>]] uses any default related model ordering
+
请记住, [[#django.db.models.query.QuerySet.order_by|order_by()]] 使用已定义的任何默认相关模型排序。 您可能必须按关系 <code>_id</code> 或引用字段显式排序,以确保 <code>DISTINCT ON</code> 表达式与 <code>ORDER BY</code> 子句开头的表达式匹配。 例如,如果 <code>Blog</code> 模型通过 <code>name</code> 定义了一个 [[../options#django.db.models.Options|ordering]]
that has been defined. You might have to explicitly order by the relation
 
<code>_id</code> or referenced field to make sure the <code>DISTINCT ON</code> expressions
 
match those at the beginning of the <code>ORDER BY</code> clause. For example, if
 
the <code>Blog</code> model defined an [[../options#django.db.models.Options|<code>ordering</code>]] by
 
<code>name</code>:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第684行: 第519行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.order_by('blog').distinct('blog')</pre>
+
<syntaxhighlight lang="python">Entry.objects.order_by('blog').distinct('blog')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
...wouldn't work because the query would be ordered by <code>blog__name</code> thus
+
……不起作用,因为查询将按 <code>blog__name</code> 排序,从而与 <code>DISTINCT ON</code> 表达式不匹配。 您必须按关系 _id 字段(在本例中为 <code>blog_id</code>)或引用的字段(<code>blog__pk</code>)明确排序,以确保两个表达式匹配。
mismatching the <code>DISTINCT ON</code> expression. You'd have to explicitly order
 
by the relation _id field (<code>blog_id</code> in this case) or the referenced
 
one (<code>blog__pk</code>) to make sure both expressions match.
 
  
  
第700行: 第532行:
 
<div id="values" class="section">
 
<div id="values" class="section">
  
==== <code>values()</code> ====
+
==== values() ====
  
; <code>values</code><span class="sig-paren">(</span>''<span class="o">*</span><span class="n">fields</span>'', ''<span class="o">**</span><span class="n">expressions</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">values</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">fields</span></span>'', ''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">expressions</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Returns a <code>QuerySet</code> that returns dictionaries, rather than model instances,
+
返回一个 <code>QuerySet</code> 返回字典,而不是模型实例。
when used as an iterable.
 
  
Each of those dictionaries represents an object, with the keys corresponding to
+
其中每一个字典都代表一个对象,键与模型对象的属性名相对应。
the attribute names of model objects.
 
  
This example compares the dictionaries of <code>values()</code> with the normal model
+
本示例将 <code>values()</code> 的字典与普通模型对象进行比较:
objects:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第718行: 第547行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre># This list contains a Blog object.
+
<syntaxhighlight lang="python"># This list contains a Blog object.
&gt;&gt;&gt; Blog.objects.filter(name__startswith='Beatles')
+
>>> Blog.objects.filter(name__startswith='Beatles')
&lt;QuerySet [&lt;Blog: Beatles Blog&gt;]&gt;
+
<QuerySet [<Blog: Beatles Blog>]>
  
 
# This list contains a dictionary.
 
# This list contains a dictionary.
&gt;&gt;&gt; Blog.objects.filter(name__startswith='Beatles').values()
+
>>> Blog.objects.filter(name__startswith='Beatles').values()
&lt;QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]&gt;</pre>
+
<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The <code>values()</code> method takes optional positional arguments, <code>*fields</code>, which
+
<code>values()</code> 方法采用可选的位置参数 <code>*fields</code>,它指定 <code>SELECT</code> 应限制为的字段名称。 如果您指定字段,则每个字典将仅包含您指定的字段的字段键/值。 如果不指定字段,则每个字典将包含数据库表中每个字段的键和值。
specify field names to which the <code>SELECT</code> should be limited. If you specify
 
the fields, each dictionary will contain only the field keys/values for the
 
fields you specify. If you don't specify the fields, each dictionary will
 
contain a key and value for every field in the database table.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第741行: 第566行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Blog.objects.values()
+
<syntaxhighlight lang="python">>>> Blog.objects.values()
&lt;QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]&gt;
+
<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]>
&gt;&gt;&gt; Blog.objects.values('id', 'name')
+
>>> Blog.objects.values('id', 'name')
&lt;QuerySet [{'id': 1, 'name': 'Beatles Blog'}]&gt;</pre>
+
<QuerySet [{'id': 1, 'name': 'Beatles Blog'}]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The <code>values()</code> method also takes optional keyword arguments,
+
<code>values()</code> 方法还接受可选的关键字参数,<code>**expressions</code>,这些参数被传递给 [[#django.db.models.query.QuerySet.annotate|annotate()]]
<code>**expressions</code>, which are passed through to [[#django.db.models.query.QuerySet.annotate|<code>annotate()</code>]]:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第756行: 第580行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; from django.db.models.functions import Lower
+
<syntaxhighlight lang="python">>>> from django.db.models.functions import Lower
&gt;&gt;&gt; Blog.objects.values(lower_name=Lower('name'))
+
>>> Blog.objects.values(lower_name=Lower('name'))
&lt;QuerySet [{'lower_name': 'beatles blog'}]&gt;</pre>
+
<QuerySet [{'lower_name': 'beatles blog'}]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
You can use built-in and [[../../../howto/custom-lookups|<span class="doc">custom lookups</span>]] in
+
您可以在排序中使用内置和 [[../../../howto/custom-lookups|自定义查找]] 。 例如:
ordering. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第770行: 第593行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; from django.db.models import CharField
+
<syntaxhighlight lang="python">>>> from django.db.models import CharField
&gt;&gt;&gt; from django.db.models.functions import Lower
+
>>> from django.db.models.functions import Lower
&gt;&gt;&gt; CharField.register_lookup(Lower)
+
>>> CharField.register_lookup(Lower)
&gt;&gt;&gt; Blog.objects.values('name__lower')
+
>>> Blog.objects.values('name__lower')
&lt;QuerySet [{'name__lower': 'beatles blog'}]&gt;</pre>
+
<QuerySet [{'name__lower': 'beatles blog'}]></syntaxhighlight>
  
 
</div>
 
</div>
第781行: 第604行:
 
<div class="versionchanged">
 
<div class="versionchanged">
  
Support for lookups was added.
+
<span class="versionmodified changed"> 2.1 版更改: </span> 添加了对查找的支持。
  
  
 
</div>
 
</div>
An aggregate within a <code>values()</code> clause is applied before other arguments
+
<code>values()</code> 子句中的聚合应用在同一 <code>values()</code> 子句中的其他参数之前。 如果您需要按另一个值分组,请将其添加到较早的 <code>values()</code> 子句中。 例如:
within the same <code>values()</code> clause. If you need to group by another value,
 
add it to an earlier <code>values()</code> clause instead. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第793行: 第614行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; from django.db.models import Count
+
<syntaxhighlight lang="python">>>> from django.db.models import Count
&gt;&gt;&gt; Blog.objects.values('entry__authors', entries=Count('entry'))
+
>>> Blog.objects.values('entry__authors', entries=Count('entry'))
&lt;QuerySet [{'entry__authors': 1, 'entries': 20}, {'entry__authors': 1, 'entries': 13}]&gt;
+
<QuerySet [{'entry__authors': 1, 'entries': 20}, {'entry__authors': 1, 'entries': 13}]>
&gt;&gt;&gt; Blog.objects.values('entry__authors').annotate(entries=Count('entry'))
+
>>> Blog.objects.values('entry__authors').annotate(entries=Count('entry'))
&lt;QuerySet [{'entry__authors': 1, 'entries': 33}]&gt;</pre>
+
<QuerySet [{'entry__authors': 1, 'entries': 33}]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
A few subtleties that are worth mentioning:
+
有几个微妙的地方值得一提:
  
 
<ul>
 
<ul>
<li><p>If you have a field called <code>foo</code> that is a
+
<li><p>如果您有一个名为 <code>foo</code> 的字段,它是一个 [[../fields#django.db.models|ForeignKey]],默认的 <code>values()</code> 调用将返回一个名为 <code>foo_id</code> 的字典键,因为这是名称存储实际值的隐藏模型属性(<code>foo</code> 属性指的是相关模型)。 当你调用 <code>values()</code> 并传入字段名称时,你可以传入 <code>foo</code> <code>foo_id</code> 并且你会得到同样的东西(字典键将匹配字段您传入的名称)。</p>
[[../fields#django.db.models|<code>ForeignKey</code>]], the default <code>values()</code> call
+
<p>例如:</p>
will return a dictionary key called <code>foo_id</code>, since this is the name
 
of the hidden model attribute that stores the actual value (the <code>foo</code>
 
attribute refers to the related model). When you are calling
 
<code>values()</code> and passing in field names, you can pass in either <code>foo</code>
 
or <code>foo_id</code> and you will get back the same thing (the dictionary key
 
will match the field name you passed in).</p>
 
<p>例子:</p>
 
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Entry.objects.values()
+
<syntaxhighlight lang="python">>>> Entry.objects.values()
&lt;QuerySet [{'blog_id': 1, 'headline': 'First Entry', ...}, ...]&gt;
+
<QuerySet [{'blog_id': 1, 'headline': 'First Entry', ...}, ...]>
  
&gt;&gt;&gt; Entry.objects.values('blog')
+
>>> Entry.objects.values('blog')
&lt;QuerySet [{'blog': 1}, ...]&gt;
+
<QuerySet [{'blog': 1}, ...]>
  
&gt;&gt;&gt; Entry.objects.values('blog_id')
+
>>> Entry.objects.values('blog_id')
&lt;QuerySet [{'blog_id': 1}, ...]&gt;</pre>
+
<QuerySet [{'blog_id': 1}, ...]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div></li>
 
</div></li>
<li><p>When using <code>values()</code> together with [[#django.db.models.query.QuerySet.distinct|<code>distinct()</code>]], be aware that
+
<li><p><code>values()</code> [[#django.db.models.query.QuerySet.distinct|distinct()]] 一起使用时,请注意排序会影响结果。 有关详细信息,请参阅 [[#django.db.models.query.QuerySet.distinct|distinct()]] 中的注释。</p></li>
ordering can affect the results. See the note in [[#django.db.models.query.QuerySet.distinct|<code>distinct()</code>]] for
+
<li><p>如果在 [[#django.db.models.query.QuerySet.extra|extra()]] 调用后使用 <code>values()</code> 子句,则 [[#django.db.models.query.QuerySet.extra|extra()]] 中由 <code>select</code> 参数定义的任何字段必须明确包含在 <code>values()</code> 调用中。 在 <code>values()</code> 调用之后进行的任何 [[#django.db.models.query.QuerySet.extra|extra()]] 调用都将忽略其额外的选定字段。</p></li>
details.</p></li>
+
<li><p>在 <code>values()</code> 之后调用 [[#django.db.models.query.QuerySet.only|only()]] [[#django.db.models.query.QuerySet.defer|defer()]] 没有意义,因此这样做会引发 <code>NotImplementedError</code></p></li>
<li><p>If you use a <code>values()</code> clause after an [[#django.db.models.query.QuerySet.extra|<code>extra()</code>]] call,
+
<li><p>组合转换和聚合需要使用两个 [[#django.db.models.query.QuerySet.annotate|annotate()]] 调用,明确地或作为 [[#django.db.models.query.QuerySet.values|values()]] 的关键字参数。 如上,如果转换已在相关字段类型上注册,则第一个 [[#django.db.models.query.QuerySet.annotate|annotate()]] 可以省略,因此以下示例是等效的:</p>
any fields defined by a <code>select</code> argument in the [[#django.db.models.query.QuerySet.extra|<code>extra()</code>]] must
 
be explicitly included in the <code>values()</code> call. Any [[#django.db.models.query.QuerySet.extra|<code>extra()</code>]] call
 
made after a <code>values()</code> call will have its extra selected fields
 
ignored.</p></li>
 
<li><p>Calling [[#django.db.models.query.QuerySet.only|<code>only()</code>]] and [[#django.db.models.query.QuerySet.defer|<code>defer()</code>]] after <code>values()</code> doesn't make
 
sense, so doing so will raise a <code>NotImplementedError</code>.</p></li>
 
<li><p>Combining transforms and aggregates requires the use of two [[#django.db.models.query.QuerySet.annotate|<code>annotate()</code>]]
 
calls, either explicitly or as keyword arguments to [[#django.db.models.query.QuerySet.values|<code>values()</code>]]. As above,
 
if the transform has been registered on the relevant field type the first
 
[[#django.db.models.query.QuerySet.annotate|<code>annotate()</code>]] can be omitted, thus the following examples are equivalent:</p>
 
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; from django.db.models import CharField, Count
+
<syntaxhighlight lang="python">>>> from django.db.models import CharField, Count
&gt;&gt;&gt; from django.db.models.functions import Lower
+
>>> from django.db.models.functions import Lower
&gt;&gt;&gt; CharField.register_lookup(Lower)
+
>>> CharField.register_lookup(Lower)
&gt;&gt;&gt; Blog.objects.values('entry__authors__name__lower').annotate(entries=Count('entry'))
+
>>> Blog.objects.values('entry__authors__name__lower').annotate(entries=Count('entry'))
&lt;QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]&gt;
+
<QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]>
&gt;&gt;&gt; Blog.objects.values(
+
>>> Blog.objects.values(
 
...    entry__authors__name__lower=Lower('entry__authors__name')
 
...    entry__authors__name__lower=Lower('entry__authors__name')
 
... ).annotate(entries=Count('entry'))
 
... ).annotate(entries=Count('entry'))
&lt;QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]&gt;
+
<QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]>
&gt;&gt;&gt; Blog.objects.annotate(
+
>>> Blog.objects.annotate(
 
...    entry__authors__name__lower=Lower('entry__authors__name')
 
...    entry__authors__name__lower=Lower('entry__authors__name')
 
... ).values('entry__authors__name__lower').annotate(entries=Count('entry'))
 
... ).values('entry__authors__name__lower').annotate(entries=Count('entry'))
&lt;QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]&gt;</pre>
+
<QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]></syntaxhighlight>
  
 
</div>
 
</div>
第866行: 第670行:
 
</div></li></ul>
 
</div></li></ul>
  
It is useful when you know you're only going to need values from a small number
+
当您知道只需要少量可用字段中的值并且不需要模型实例对象的功能时,它很有用。 仅选择需要使用的字段会更有效率。
of the available fields and you won't need the functionality of a model
 
instance object. It's more efficient to select only the fields you need to use.
 
  
Finally, note that you can call <code>filter()</code>, <code>order_by()</code>, etc. after the
+
最后,注意可以调用<code>filter()</code><code>order_by()</code>等。 在 <code>values()</code> 调用之后,这意味着这两个调用是相同的:
<code>values()</code> call, that means that these two calls are identical:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第877行: 第678行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Blog.objects.values().order_by('id')
+
<syntaxhighlight lang="python">Blog.objects.values().order_by('id')
Blog.objects.order_by('id').values()</pre>
+
Blog.objects.order_by('id').values()</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The people who made Django prefer to put all the SQL-affecting methods first,
+
制作 Django 的人更喜欢将所有影响 SQL 的方法放在第一位,然后(可选)任何影响输出的方法(例如 <code>values()</code>),但这并不重要。 这是你真正炫耀个人主义的机会。
followed (optionally) by any output-affecting methods (such as <code>values()</code>),
 
but it doesn't really matter. This is your chance to really flaunt your
 
individualism.
 
  
You can also refer to fields on related models with reverse relations through
+
您还可以通过 <code>OneToOneField</code><code>ForeignKey</code> <code>ManyToManyField</code> 属性引用具有反向关系的相关模型上的字段:
<code>OneToOneField</code>, <code>ForeignKey</code> and <code>ManyToManyField</code> attributes:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第895行: 第692行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Blog.objects.values('name', 'entry__headline')
+
<syntaxhighlight lang="python">>>> Blog.objects.values('name', 'entry__headline')
&lt;QuerySet [{'name': 'My blog', 'entry__headline': 'An entry'},
+
<QuerySet [{'name': 'My blog', 'entry__headline': 'An entry'},
     {'name': 'My blog', 'entry__headline': 'Another entry'}, ...]&gt;</pre>
+
     {'name': 'My blog', 'entry__headline': 'Another entry'}, ...]></syntaxhighlight>
  
 
</div>
 
</div>
第906行: 第703行:
 
警告
 
警告
  
Because [[../fields#django.db.models|<code>ManyToManyField</code>]] attributes and reverse
+
因为 [[../fields#django.db.models|ManyToManyField]] 属性和反向关系可以有多个相关行,包括这些可以对结果集的大小产生乘数效应。 如果您在 <code>values()</code> 查询中包含多个这样的字段,这将特别明显,在这种情况下,将返回所有可能的组合。
relations can have multiple related rows, including these can have a
 
multiplier effect on the size of your result set. This will be especially
 
pronounced if you include multiple such fields in your <code>values()</code> query,
 
in which case all possible combinations will be returned.
 
  
  
第918行: 第711行:
 
<div id="values-list" class="section">
 
<div id="values-list" class="section">
  
==== <code>values_list()</code> ====
+
==== values_list() ====
  
; <code>values_list</code><span class="sig-paren">(</span>''<span class="o">*</span><span class="n">fields</span>'', ''<span class="n">flat</span><span class="o">=</span><span class="default_value">False</span>'', ''<span class="n">named</span><span class="o">=</span><span class="default_value">False</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">values_list</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">fields</span></span>'', ''<span class="n"><span class="pre">flat</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span>'', ''<span class="n"><span class="pre">named</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
This is similar to <code>values()</code> except that instead of returning dictionaries,
+
这类似于 <code>values()</code> 不同之处在于它在迭代时返回元组而不是返回字典。 每个元组包含来自传递到 <code>values_list()</code> 调用的相应字段或表达式的值——所以第一项是第一个字段,依此类推。 例如:
it returns tuples when iterated over. Each tuple contains the value from the
 
respective field or expression passed into the <code>values_list()</code> call — so the
 
first item is the first field, etc. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第932行: 第722行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Entry.objects.values_list('id', 'headline')
+
<syntaxhighlight lang="python">>>> Entry.objects.values_list('id', 'headline')
&lt;QuerySet [(1, 'First entry'), ...]&gt;
+
<QuerySet [(1, 'First entry'), ...]>
&gt;&gt;&gt; from django.db.models.functions import Lower
+
>>> from django.db.models.functions import Lower
&gt;&gt;&gt; Entry.objects.values_list('id', Lower('headline'))
+
>>> Entry.objects.values_list('id', Lower('headline'))
&lt;QuerySet [(1, 'first entry'), ...]&gt;</pre>
+
<QuerySet [(1, 'first entry'), ...]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
If you only pass in a single field, you can also pass in the <code>flat</code>
+
如果只传入单个字段,还可以传入 <code>flat</code> 参数。 如果 <code>True</code>,这将意味着返回的结果是单个值,而不是一元组。 一个例子应该能让区别更清楚:
parameter. If <code>True</code>, this will mean the returned results are single values,
 
rather than one-tuples. An example should make the difference clearer:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第949行: 第737行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Entry.objects.values_list('id').order_by('id')
+
<syntaxhighlight lang="python">>>> Entry.objects.values_list('id').order_by('id')
&lt;QuerySet[(1,), (2,), (3,), ...]&gt;
+
<QuerySet[(1,), (2,), (3,), ...]>
  
&gt;&gt;&gt; Entry.objects.values_list('id', flat=True).order_by('id')
+
>>> Entry.objects.values_list('id', flat=True).order_by('id')
&lt;QuerySet [1, 2, 3, ...]&gt;</pre>
+
<QuerySet [1, 2, 3, ...]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
It is an error to pass in <code>flat</code> when there is more than one field.
+
有多个字段时传入<code>flat</code>是错误的。
  
You can pass <code>named=True</code> to get results as a
+
您可以通过 <code>named=True</code> 来获得作为 <code>namedtuple()</code> 的结果:
<code>namedtuple()</code>:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第967行: 第754行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Entry.objects.values_list('id', 'headline', named=True)
+
<syntaxhighlight lang="python">>>> Entry.objects.values_list('id', 'headline', named=True)
&lt;QuerySet [Row(id=1, headline='First entry'), ...]&gt;</pre>
+
<QuerySet [Row(id=1, headline='First entry'), ...]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Using a named tuple may make use of the results more readable, at the expense
+
使用命名元组可能会使使用结果更易读,但代价是将结果转化为命名元组时要付出很小的性能代价。
of a small performance penalty for transforming the results into a named tuple.
 
  
If you don't pass any values to <code>values_list()</code>, it will return all the
+
如果您没有将任何值传递给 <code>values_list()</code>,它将按照声明的顺序返回模型中的所有字段。
fields in the model, in the order they were declared.
 
  
A common need is to get a specific field value of a certain model instance. To
+
一个常见的需求是获取某个模型实例的特定字段值。 为此,请使用 <code>values_list()</code> 后跟 <code>get()</code> 调用:
achieve that, use <code>values_list()</code> followed by a <code>get()</code> call:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第986行: 第770行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Entry.objects.values_list('headline', flat=True).get(pk=1)
+
<syntaxhighlight lang="python">>>> Entry.objects.values_list('headline', flat=True).get(pk=1)
'First entry'</pre>
+
'First entry'</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<code>values()</code> and <code>values_list()</code> are both intended as optimizations for a
+
<code>values()</code> <code>values_list()</code> 都是针对特定用例的优化:在没有创建模型实例的开销的情况下检索数据子集。 当处理多对多和其他多值关系(例如反向外键的一对多关系)时,这个比喻就失效了,因为“一行一个对象”假设不成立。
specific use case: retrieving a subset of data without the overhead of creating
 
a model instance. This metaphor falls apart when dealing with many-to-many and
 
other multivalued relations (such as the one-to-many relation of a reverse
 
foreign key) because the &quot;one row, one object&quot; assumption doesn't hold.
 
  
For example, notice the behavior when querying across a
+
例如,请注意跨 [[../fields#django.db.models|ManyToManyField]] 查询时的行为:
[[../fields#django.db.models|<code>ManyToManyField</code>]]:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,005行: 第784行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Author.objects.values_list('name', 'entry__headline')
+
<syntaxhighlight lang="python">>>> Author.objects.values_list('name', 'entry__headline')
&lt;QuerySet [('Noam Chomsky', 'Impressions of Gaza'),
+
<QuerySet [('Noam Chomsky', 'Impressions of Gaza'),
 
  ('George Orwell', 'Why Socialists Do Not Believe in Fun'),
 
  ('George Orwell', 'Why Socialists Do Not Believe in Fun'),
 
  ('George Orwell', 'In Defence of English Cooking'),
 
  ('George Orwell', 'In Defence of English Cooking'),
  ('Don Quixote', None)]&gt;</pre>
+
  ('Don Quixote', None)]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Authors with multiple entries appear multiple times and authors without any
+
有多个条目的作者多次出现,没有任何条目的作者的条目标题为 <code>None</code>
entries have <code>None</code> for the entry headline.
 
  
Similarly, when querying a reverse foreign key, <code>None</code> appears for entries
+
同样,当查询反向外键时,对于没有任何作者的条目,会出现 <code>None</code>
not having any author:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,024行: 第801行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Entry.objects.values_list('authors')
+
<syntaxhighlight lang="python">>>> Entry.objects.values_list('authors')
&lt;QuerySet [('Noam Chomsky',), ('George Orwell',), (None,)]&gt;</pre>
+
<QuerySet [('Noam Chomsky',), ('George Orwell',), (None,)]></syntaxhighlight>
  
 
</div>
 
</div>
第1,034行: 第811行:
 
<div id="dates" class="section">
 
<div id="dates" class="section">
  
==== <code>dates()</code> ====
+
==== dates() ====
  
; <code>dates</code><span class="sig-paren">(</span>''<span class="n">field</span>'', ''<span class="n">kind</span>'', ''<span class="n">order</span><span class="o">=</span><span class="default_value">'ASC'</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">dates</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">field</span></span>'', ''<span class="n"><span class="pre">kind</span></span>'', ''<span class="n"><span class="pre">order</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">'ASC'</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Returns a <code>QuerySet</code> that evaluates to a list of <code>datetime.date</code>
+
返回一个 <code>QuerySet</code>,其计算结果为 <code>datetime.date</code> 对象列表,表示 <code>QuerySet</code> 内容中特定类型的所有可用日期。
objects representing all available dates of a particular kind within the
 
contents of the <code>QuerySet</code>.
 
  
<code>field</code> should be the name of a <code>DateField</code> of your model.
+
<code>field</code> 应该是您模型的 <code>DateField</code> 的名称。 <code>kind</code> 应为 <code>&quot;year&quot;</code><code>&quot;month&quot;</code><code>&quot;week&quot;</code> <code>&quot;day&quot;</code>。 结果列表中的每个 <code>datetime.date</code> 对象都被“截断”为给定的 <code>type</code>
<code>kind</code> should be either <code>&quot;year&quot;</code>, <code>&quot;month&quot;</code>, <code>&quot;week&quot;</code>, or <code>&quot;day&quot;</code>.
 
Each <code>datetime.date</code> object in the result list is &quot;truncated&quot; to the
 
given <code>type</code>.
 
  
* <code>&quot;year&quot;</code> returns a list of all distinct year values for the field.
+
* <code>&quot;year&quot;</code> 返回字段的所有不同年份值的列表。
* <code>&quot;month&quot;</code> returns a list of all distinct year/month values for the field.
+
* <code>&quot;month&quot;</code> 返回字段的所有不同年/月值的列表。
* <code>&quot;week&quot;</code> returns a list of all distinct year/week values for the field. All dates will be a Monday.
+
* <code>&quot;week&quot;</code> 返回该字段所有不同年/周值的列表。 所有日期都将是星期一。
* <code>&quot;day&quot;</code> returns a list of all distinct year/month/day values for the field.
+
* <code>&quot;day&quot;</code> 返回字段的所有不同年//日值的列表。
  
<code>order</code>, which defaults to <code>'ASC'</code>, should be either <code>'ASC'</code> or
+
<code>order</code>,默认为 <code>'ASC'</code>,应该是 <code>'ASC'</code> <code>'DESC'</code>。 这指定了如何对结果进行排序。
<code>'DESC'</code>. This specifies how to order the results.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,062行: 第833行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Entry.objects.dates('pub_date', 'year')
+
<syntaxhighlight lang="python">>>> Entry.objects.dates('pub_date', 'year')
 
[datetime.date(2005, 1, 1)]
 
[datetime.date(2005, 1, 1)]
&gt;&gt;&gt; Entry.objects.dates('pub_date', 'month')
+
>>> Entry.objects.dates('pub_date', 'month')
 
[datetime.date(2005, 2, 1), datetime.date(2005, 3, 1)]
 
[datetime.date(2005, 2, 1), datetime.date(2005, 3, 1)]
&gt;&gt;&gt; Entry.objects.dates('pub_date', 'week')
+
>>> Entry.objects.dates('pub_date', 'week')
 
[datetime.date(2005, 2, 14), datetime.date(2005, 3, 14)]
 
[datetime.date(2005, 2, 14), datetime.date(2005, 3, 14)]
&gt;&gt;&gt; Entry.objects.dates('pub_date', 'day')
+
>>> Entry.objects.dates('pub_date', 'day')
 
[datetime.date(2005, 2, 20), datetime.date(2005, 3, 20)]
 
[datetime.date(2005, 2, 20), datetime.date(2005, 3, 20)]
&gt;&gt;&gt; Entry.objects.dates('pub_date', 'day', order='DESC')
+
>>> Entry.objects.dates('pub_date', 'day', order='DESC')
 
[datetime.date(2005, 3, 20), datetime.date(2005, 2, 20)]
 
[datetime.date(2005, 3, 20), datetime.date(2005, 2, 20)]
&gt;&gt;&gt; Entry.objects.filter(headline__contains='Lennon').dates('pub_date', 'day')
+
>>> Entry.objects.filter(headline__contains='Lennon').dates('pub_date', 'day')
[datetime.date(2005, 3, 20)]</pre>
+
[datetime.date(2005, 3, 20)]</syntaxhighlight>
  
 
</div>
 
</div>
第1,080行: 第851行:
 
<div class="versionchanged">
 
<div class="versionchanged">
  
&quot;week&quot; support was added.
+
<span class="versionmodified changed"> 2.1 版变更: </span> 增加了“周”支持。
  
  
第1,088行: 第859行:
 
<div id="datetimes" class="section">
 
<div id="datetimes" class="section">
  
==== <code>datetimes()</code> ====
+
==== datetimes() ====
  
; <code>datetimes</code><span class="sig-paren">(</span>''<span class="n">field_name</span>'', ''<span class="n">kind</span>'', ''<span class="n">order</span><span class="o">=</span><span class="default_value">'ASC'</span>'', ''<span class="n">tzinfo</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">datetimes</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">field_name</span></span>'', ''<span class="n"><span class="pre">kind</span></span>'', ''<span class="n"><span class="pre">order</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">'ASC'</span></span>'', ''<span class="n"><span class="pre">tzinfo</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Returns a <code>QuerySet</code> that evaluates to a list of <code>datetime.datetime</code>
+
返回一个 <code>QuerySet</code>,其计算结果为 <code>datetime.datetime</code> 对象列表,表示 <code>QuerySet</code> 内容中特定类型的所有可用日期。
objects representing all available dates of a particular kind within the
 
contents of the <code>QuerySet</code>.
 
  
<code>field_name</code> should be the name of a <code>DateTimeField</code> of your model.
+
<code>field_name</code> 应该是您模型的 <code>DateTimeField</code> 的名称。
  
<code>kind</code> should be either <code>&quot;year&quot;</code>, <code>&quot;month&quot;</code>, <code>&quot;week&quot;</code>, <code>&quot;day&quot;</code>,
+
<code>kind</code> 应为 <code>&quot;year&quot;</code><code>&quot;month&quot;</code><code>&quot;week&quot;</code><code>&quot;day&quot;</code><code>&quot;hour&quot;</code><code>&quot;minute&quot;</code> , <code>&quot;second&quot;</code>。 结果列表中的每个 <code>datetime.datetime</code> 对象都被“截断”为给定的 <code>type</code>
<code>&quot;hour&quot;</code>, <code>&quot;minute&quot;</code>, or <code>&quot;second&quot;</code>. Each <code>datetime.datetime</code>
 
object in the result list is &quot;truncated&quot; to the given <code>type</code>.
 
  
<code>order</code>, which defaults to <code>'ASC'</code>, should be either <code>'ASC'</code> or
+
<code>order</code>,默认为 <code>'ASC'</code>,应该是 <code>'ASC'</code> <code>'DESC'</code>。 这指定了如何对结果进行排序。
<code>'DESC'</code>. This specifies how to order the results.
 
  
<code>tzinfo</code> defines the time zone to which datetimes are converted prior to
+
<code>tzinfo</code> 定义日期时间在截断之前转换到的时区。 实际上,根据使用的时区,给定的日期时间具有不同的表示形式。 此参数必须是 <code>datetime.tzinfo</code> 对象。 如果是 <code>None</code>,Django 使用 [[../../../topics/i18n/timezones#default-current-time-zone|当前时区]] [[#id4|:setting:`USE_TZ`]] <code>False</code> 时无效。
truncation. Indeed, a given datetime has different representations depending
 
on the time zone in use. This parameter must be a <code>datetime.tzinfo</code>
 
object. If it's <code>None</code>, Django uses the [[../../../topics/i18n/timezones#default-current-time-zone|<span class="std std-ref">current time zone</span>]]. It has no effect when [[../../settings#std-setting-USE_TZ|<code>USE_TZ</code>]] is
 
<code>False</code>.
 
  
 
<div class="versionchanged">
 
<div class="versionchanged">
  
&quot;week&quot; support was added.
+
<span class="versionmodified changed"> 2.1 版变更: </span> 增加了“周”支持。
  
  
第1,122行: 第884行:
 
注解
 
注解
  
This function performs time zone conversions directly in the database.
+
此函数直接在数据库中执行时区转换。 因此,您的数据库必须能够解释 <code>tzinfo.tzname(None)</code> 的值。 这转化为以下要求:
As a consequence, your database must be able to interpret the value of
 
<code>tzinfo.tzname(None)</code>. This translates into the following requirements:
 
  
* SQLite: no requirements. Conversions are performed in Python with [http://pytz.sourceforge.net/ pytz] (installed when you install Django).
+
* SQLite:没有要求。 使用 [http://pytz.sourceforge.net/ pytz](安装 Django 时安装)在 Python 中执行转换。
* PostgreSQL: no requirements (see [https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-TIMEZONES Time Zones]).
+
* PostgreSQL:无要求(参见 [https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-TIMEZONES 时区] )。
* Oracle: no requirements (see [https://docs.oracle.com/en/database/oracle/oracle-database/18/nlspg/datetime-data-types-and-time-zone-support.html#GUID-805AB986-DE12-4FEA-AF56-5AABCD2132DF Choosing a Time Zone File]).
+
* Oracle:无要求(请参阅 [https://docs.oracle.com/en/database/oracle/oracle-database/18/nlspg/datetime-data-types-and-time-zone-support.html#GUID-805AB986-DE12-4FEA-AF56-5AABCD2132DF 选择时区文件] )。
* MySQL: load the time zone tables with [https://dev.mysql.com/doc/refman/en/mysql-tzinfo-to-sql.html mysql_tzinfo_to_sql].
+
* MySQL:使用 [https://dev.mysql.com/doc/refman/en/mysql-tzinfo-to-sql.html mysql_tzinfo_to_sql] 加载时区表。
  
  
第1,137行: 第897行:
 
<div id="none" class="section">
 
<div id="none" class="section">
  
==== <code>none()</code> ====
+
==== none() ====
  
; <code>none</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">none</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
 
:  
 
:  
  
Calling none() will create a queryset that never returns any objects and no
+
调用 none() 将创建一个永远不会返回任何对象的查询集,并且在访问结果时不会执行任何查询。 qs.none() 查询集是 <code>EmptyQuerySet</code> 的一个实例。
query will be executed when accessing the results. A qs.none() queryset
 
is an instance of <code>EmptyQuerySet</code>.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,152行: 第910行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Entry.objects.none()
+
<syntaxhighlight lang="python">>>> Entry.objects.none()
&lt;QuerySet []&gt;
+
<QuerySet []>
&gt;&gt;&gt; from django.db.models.query import EmptyQuerySet
+
>>> from django.db.models.query import EmptyQuerySet
&gt;&gt;&gt; isinstance(Entry.objects.none(), EmptyQuerySet)
+
>>> isinstance(Entry.objects.none(), EmptyQuerySet)
True</pre>
+
True</syntaxhighlight>
  
 
</div>
 
</div>
第1,165行: 第923行:
 
<div id="all" class="section">
 
<div id="all" class="section">
  
==== <code>all()</code> ====
+
==== all() ====
  
; <code>all</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">all</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
 
:  
 
:  
  
Returns a ''copy'' of the current <code>QuerySet</code> (or <code>QuerySet</code> subclass). This
+
返回当前 <code>QuerySet</code>(或 <code>QuerySet</code> 子类)的 ''副本'' 。 这在您可能希望传入模型管理器或 <code>QuerySet</code> 并对结果进行进一步过滤的情况下非常有用。 在任一对象上调用 <code>all()</code> 之后,您肯定会有一个 <code>QuerySet</code> 可以使用。
can be useful in situations where you might want to pass in either a model
 
manager or a <code>QuerySet</code> and do further filtering on the result. After calling
 
<code>all()</code> on either object, you'll definitely have a <code>QuerySet</code> to work with.
 
  
When a <code>QuerySet</code> is [[#when-querysets-are-evaluated|<span class="std std-ref">evaluated</span>]], it
+
<code>QuerySet</code> [[#when-querysets-are-evaluated|评估]] 时,它通常会缓存其结果。 如果自评估 <code>QuerySet</code> 后数据库中的数据可能已更改,您可以通过对先前评估的 <code>QuerySet</code> 调用 <code>all()</code> 来获取同一查询的更新结果。
typically caches its results. If the data in the database might have changed
 
since a <code>QuerySet</code> was evaluated, you can get updated results for the same
 
query by calling <code>all()</code> on a previously evaluated <code>QuerySet</code>.
 
  
  
第1,184行: 第936行:
 
<div id="union" class="section">
 
<div id="union" class="section">
  
==== <code>union()</code> ====
+
==== union() ====
  
; <code>union</code><span class="sig-paren">(</span>''<span class="o">*</span><span class="n">other_qs</span>'', ''<span class="n">all</span><span class="o">=</span><span class="default_value">False</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">union</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">other_qs</span></span>'', ''<span class="n"><span class="pre">all</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Uses SQL's <code>UNION</code> operator to combine the results of two or more
+
使用 SQL <code>UNION</code> 运算符组合两个或多个 <code>QuerySet</code> 的结果。 例如:
<code>QuerySet</code>s. For example:
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,196行: 第947行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; qs1.union(qs2, qs3)</pre>
+
<syntaxhighlight lang="python">>>> qs1.union(qs2, qs3)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The <code>UNION</code> operator selects only distinct values by default. To allow
+
默认情况下,<code>UNION</code> 运算符仅选择不同的值。 要允许重复值,请使用 <code>all=True</code> 参数。
duplicate values, use the <code>all=True</code> argument.
 
  
<code>union()</code>, <code>intersection()</code>, and <code>difference()</code> return model instances
+
<code>union()</code><code>intersection()</code> <code>difference()</code> 返回第一个 <code>QuerySet</code> 类型的模型实例,即使参数是其他的 <code>QuerySet</code>楷模。 只要 <code>SELECT</code> 列表在所有 <code>QuerySet</code> 中都相同(至少是类型,名称无关紧要,只要类型的顺序相同)就可以传递不同的模型。 在这种情况下,您必须使用应用到结果 <code>QuerySet</code> <code>QuerySet</code> 方法中第一个 <code>QuerySet</code> 的列名。 例如:
of the type of the first <code>QuerySet</code> even if the arguments are <code>QuerySet</code>s
 
of other models. Passing different models works as long as the <code>SELECT</code> list
 
is the same in all <code>QuerySet</code>s (at least the types, the names don't matter
 
as long as the types in the same order). In such cases, you must use the column
 
names from the first <code>QuerySet</code> in <code>QuerySet</code> methods applied to the
 
resulting <code>QuerySet</code>. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,216行: 第960行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; qs1 = Author.objects.values_list('name')
+
<syntaxhighlight lang="python">>>> qs1 = Author.objects.values_list('name')
&gt;&gt;&gt; qs2 = Entry.objects.values_list('headline')
+
>>> qs2 = Entry.objects.values_list('headline')
&gt;&gt;&gt; qs1.union(qs2).order_by('name')</pre>
+
>>> qs1.union(qs2).order_by('name')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
In addition, only <code>LIMIT</code>, <code>OFFSET</code>, <code>COUNT(*)</code>, <code>ORDER BY</code>, and
+
此外,只有 <code>LIMIT</code><code>OFFSET</code><code>COUNT(*)</code><code>ORDER BY</code>,并指定列(即 切片,[[#django.db.models.query.QuerySet.count|count()]][[#django.db.models.query.QuerySet.order_by|order_by()]] [[#django.db.models.query.QuerySet.values|values()]]/[[#django.db.models.query.QuerySet.values_list|values_list()]]) 允许在结果 [X123X ]。 此外,数据库对组合查询中允许的操作进行了限制。 例如,大多数数据库不允许在组合查询中使用 <code>LIMIT</code> <code>OFFSET</code>
specifying columns (i.e. slicing, [[#django.db.models.query.QuerySet.count|<code>count()</code>]], [[#django.db.models.query.QuerySet.order_by|<code>order_by()</code>]], and
 
[[#django.db.models.query.QuerySet.values|<code>values()</code>]]/[[#django.db.models.query.QuerySet.values_list|<code>values_list()</code>]]) are allowed on the resulting
 
<code>QuerySet</code>. Further, databases place restrictions on what operations are
 
allowed in the combined queries. For example, most databases don't allow
 
<code>LIMIT</code> or <code>OFFSET</code> in the combined queries.
 
  
  
第1,234行: 第973行:
 
<div id="intersection" class="section">
 
<div id="intersection" class="section">
  
==== <code>intersection()</code> ====
+
==== intersection() ====
  
; <code>intersection</code><span class="sig-paren">(</span>''<span class="o">*</span><span class="n">other_qs</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">intersection</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">other_qs</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Uses SQL's <code>INTERSECT</code> operator to return the shared elements of two or more
+
使用 SQL <code>INTERSECT</code> 运算符返回两个或多个 <code>QuerySet</code> 的共享元素。 例如:
<code>QuerySet</code>s. For example:
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,246行: 第984行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; qs1.intersection(qs2, qs3)</pre>
+
<syntaxhighlight lang="python">>>> qs1.intersection(qs2, qs3)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
See [[#django.db.models.query.QuerySet.union|<code>union()</code>]] for some restrictions.
+
有关一些限制,请参阅 [[#django.db.models.query.QuerySet.union|union()]]
  
  
第1,257行: 第995行:
 
<div id="difference" class="section">
 
<div id="difference" class="section">
  
==== <code>difference()</code> ====
+
==== difference() ====
  
; <code>difference</code><span class="sig-paren">(</span>''<span class="o">*</span><span class="n">other_qs</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">difference</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">other_qs</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Uses SQL's <code>EXCEPT</code> operator to keep only elements present in the
+
使用 SQL <code>EXCEPT</code> 运算符仅保留 <code>QuerySet</code> 中存在的元素,而不保留其他一些 <code>QuerySet</code> 中的元素。 例如:
<code>QuerySet</code> but not in some other <code>QuerySet</code>s. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,269行: 第1,006行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; qs1.difference(qs2, qs3)</pre>
+
<syntaxhighlight lang="python">>>> qs1.difference(qs2, qs3)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
See [[#django.db.models.query.QuerySet.union|<code>union()</code>]] for some restrictions.
+
有关一些限制,请参阅 [[#django.db.models.query.QuerySet.union|union()]]
  
  
第1,280行: 第1,017行:
 
<div id="select-related" class="section">
 
<div id="select-related" class="section">
  
==== <code>select_related()</code> ====
+
==== select_related() ====
  
; <code>select_related</code><span class="sig-paren">(</span>''<span class="o">*</span><span class="n">fields</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">select_related</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">fields</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Returns a <code>QuerySet</code> that will &quot;follow&quot; foreign-key relationships, selecting
+
返回一个 <code>QuerySet</code>,它将“遵循”外键关系,在执行查询时选择其他相关对象数据。 这是一个性能助推器,它导致一个更复杂的查询,但意味着以后使用外键关系不需要数据库查询。
additional related-object data when it executes its query. This is a
 
performance booster which results in a single more complex query but means
 
later use of foreign-key relationships won't require database queries.
 
  
The following examples illustrate the difference between plain lookups and
+
以下示例说明了普通查找和 <code>select_related()</code> 查找之间的区别。 这是标准查找:
<code>select_related()</code> lookups. Here's standard lookup:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,297行: 第1,030行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre># Hits the database.
+
<syntaxhighlight lang="python"># Hits the database.
 
e = Entry.objects.get(id=5)
 
e = Entry.objects.get(id=5)
  
 
# Hits the database again to get the related Blog object.
 
# Hits the database again to get the related Blog object.
b = e.blog</pre>
+
b = e.blog</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
And here's <code>select_related</code> lookup:
+
这是 <code>select_related</code> 查找:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,312行: 第1,045行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre># Hits the database.
+
<syntaxhighlight lang="python"># Hits the database.
 
e = Entry.objects.select_related('blog').get(id=5)
 
e = Entry.objects.select_related('blog').get(id=5)
  
 
# Doesn't hit the database, because e.blog has been prepopulated
 
# Doesn't hit the database, because e.blog has been prepopulated
 
# in the previous query.
 
# in the previous query.
b = e.blog</pre>
+
b = e.blog</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
You can use <code>select_related()</code> with any queryset of objects:
+
您可以将 <code>select_related()</code> 与任何对象查询集一起使用:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,328行: 第1,061行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.utils import timezone
+
<syntaxhighlight lang="python">from django.utils import timezone
  
 
# Find all the blogs with entries scheduled to be published in the future.
 
# Find all the blogs with entries scheduled to be published in the future.
第1,336行: 第1,069行:
 
     # Without select_related(), this would make a database query for each
 
     # Without select_related(), this would make a database query for each
 
     # loop iteration in order to fetch the related blog for each entry.
 
     # loop iteration in order to fetch the related blog for each entry.
     blogs.add(e.blog)</pre>
+
     blogs.add(e.blog)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The order of <code>filter()</code> and <code>select_related()</code> chaining isn't important.
+
<code>filter()</code> <code>select_related()</code> 链接的顺序并不重要。 这些查询集是等效的:
These querysets are equivalent:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,348行: 第1,080行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(pub_date__gt=timezone.now()).select_related('blog')
+
<syntaxhighlight lang="python">Entry.objects.filter(pub_date__gt=timezone.now()).select_related('blog')
Entry.objects.select_related('blog').filter(pub_date__gt=timezone.now())</pre>
+
Entry.objects.select_related('blog').filter(pub_date__gt=timezone.now())</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
You can follow foreign keys in a similar way to querying them. If you have the
+
您可以按照与查询类似的方式跟踪外键。 如果您有以下型号:
following models:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,361行: 第1,092行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.db import models
+
<syntaxhighlight lang="python">from django.db import models
  
 
class City(models.Model):
 
class City(models.Model):
第1,378行: 第1,109行:
 
class Book(models.Model):
 
class Book(models.Model):
 
     # ...
 
     # ...
     author = models.ForeignKey(Person, on_delete=models.CASCADE)</pre>
+
     author = models.ForeignKey(Person, on_delete=models.CASCADE)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
... then a call to <code>Book.objects.select_related('author__hometown').get(id=4)</code>
+
...然后调用 <code>Book.objects.select_related('author__hometown').get(id=4)</code> 将缓存相关的 <code>Person</code> '''' 相关的 <code>City</code>
will cache the related <code>Person</code> ''and'' the related <code>City</code>:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,390行: 第1,120行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre># Hits the database with joins to the author and hometown tables.
+
<syntaxhighlight lang="python"># Hits the database with joins to the author and hometown tables.
 
b = Book.objects.select_related('author__hometown').get(id=4)
 
b = Book.objects.select_related('author__hometown').get(id=4)
 
p = b.author        # Doesn't hit the database.
 
p = b.author        # Doesn't hit the database.
第1,398行: 第1,128行:
 
b = Book.objects.get(id=4)  # Hits the database.
 
b = Book.objects.get(id=4)  # Hits the database.
 
p = b.author        # Hits the database.
 
p = b.author        # Hits the database.
c = p.hometown      # Hits the database.</pre>
+
c = p.hometown      # Hits the database.</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
You can refer to any [[../fields#django.db.models|<code>ForeignKey</code>]] or
+
您可以在传递给 <code>select_related()</code> 的字段列表中引用任何 [[../fields#django.db.models|ForeignKey]] [[../fields#django.db.models|OneToOneField]] 关系。
[[../fields#django.db.models|<code>OneToOneField</code>]] relation in the list of fields
 
passed to <code>select_related()</code>.
 
  
You can also refer to the reverse direction of a
+
还可以参考传递给 <code>select_related</code> 的字段列表中的 [[../fields#django.db.models|OneToOneField]] 的反向——也就是说,可以遍历一个 [[../fields#django.db.models|OneToOneField]] 回到对象上定义了哪个字段。 不要指定字段名称,而是使用 [[../fields#django.db.models.ForeignKey|related_name]] 作为相关对象上的字段。
[[../fields#django.db.models|<code>OneToOneField</code>]] in the list of fields passed to
 
<code>select_related</code> — that is, you can traverse a
 
[[../fields#django.db.models|<code>OneToOneField</code>]] back to the object on which the field
 
is defined. Instead of specifying the field name, use the [[../fields#django.db.models.ForeignKey|<code>related_name</code>]] for the field on the related object.
 
  
There may be some situations where you wish to call <code>select_related()</code> with a
+
在某些情况下,您可能希望使用大量相关对象调用 <code>select_related()</code>,或者您不知道所有关系。 在这些情况下,可以不带参数调用 <code>select_related()</code>。 这将遵循它可以找到的所有非空外键 - 必须指定可为空的外键。 在大多数情况下不建议这样做,因为它可能会使基础查询更复杂,并返回比实际需要更多的数据。
lot of related objects, or where you don't know all of the relations. In these
 
cases it is possible to call <code>select_related()</code> with no arguments. This will
 
follow all non-null foreign keys it can find - nullable foreign keys must be
 
specified. This is not recommended in most cases as it is likely to make the
 
underlying query more complex, and return more data, than is actually needed.
 
  
If you need to clear the list of related fields added by past calls of
+
如果需要清除 <code>QuerySet</code> 上过去调用 <code>select_related</code> 添加的相关字段列表,可以将 <code>None</code> 作为参数传递:
<code>select_related</code> on a <code>QuerySet</code>, you can pass <code>None</code> as a parameter:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,427行: 第1,145行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; without_relations = queryset.select_related(None)</pre>
+
<syntaxhighlight lang="python">>>> without_relations = queryset.select_related(None)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Chaining <code>select_related</code> calls works in a similar way to other methods -
+
链接 <code>select_related</code> 调用的工作方式与其他方法类似 - <code>select_related('foo', 'bar')</code> 等效于 <code>select_related('foo').select_related('bar')</code>
that is that <code>select_related('foo', 'bar')</code> is equivalent to
 
<code>select_related('foo').select_related('bar')</code>.
 
  
  
第1,440行: 第1,156行:
 
<div id="prefetch-related" class="section">
 
<div id="prefetch-related" class="section">
  
==== <code>prefetch_related()</code> ====
+
==== prefetch_related() ====
  
; <code>prefetch_related</code><span class="sig-paren">(</span>''<span class="o">*</span><span class="n">lookups</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">prefetch_related</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">lookups</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Returns a <code>QuerySet</code> that will automatically retrieve, in a single batch,
+
返回一个 <code>QuerySet</code>,它将自动为每个指定的查找批量检索相关对象。
related objects for each of the specified lookups.
 
  
This has a similar purpose to <code>select_related</code>, in that both are designed to
+
这与 <code>select_related</code> 的目的相似,都旨在阻止因访问相关对象而导致的数据库查询泛滥,但策略却大不相同。
stop the deluge of database queries that is caused by accessing related objects,
 
but the strategy is quite different.
 
  
<code>select_related</code> works by creating an SQL join and including the fields of the
+
<code>select_related</code> 通过创建 SQL 连接并在 <code>SELECT</code> 语句中包含相关对象的字段来工作。 为此,<code>select_related</code> 在同一个数据库查询中获取相关对象。 但是,为了避免因跨“多”关系加入而导致的更大的结果集,<code>select_related</code> 仅限于单值关系 - 外键和一对一。
related object in the <code>SELECT</code> statement. For this reason, <code>select_related</code>
 
gets the related objects in the same database query. However, to avoid the much
 
larger result set that would result from joining across a 'many' relationship,
 
<code>select_related</code> is limited to single-valued relationships - foreign key and
 
one-to-one.
 
  
<code>prefetch_related</code>, on the other hand, does a separate lookup for each
+
另一方面,<code>prefetch_related</code> 对每个关系进行单独的查找,并在 Python 中进行“连接”。 除了<code>select_related</code>。 它还支持 [X32X]GenericRelation [[../../contrib/contenttypes#django.contrib.contenttypes.fields|GenericForeignKey]] 的预取,但是,它必须限制为一组同构的结果。 例如,仅当查询限制为一个 <code>ContentType</code> 时,才支持预取由 <code>GenericForeignKey</code> 引用的对象。
relationship, and does the 'joining' in Python. This allows it to prefetch
 
many-to-many and many-to-one objects, which cannot be done using
 
<code>select_related</code>, in addition to the foreign key and one-to-one relationships
 
that are supported by <code>select_related</code>. It also supports prefetching of
 
[[../../contrib/contenttypes#django.contrib.contenttypes.fields|<code>GenericRelation</code>]] and
 
[[../../contrib/contenttypes#django.contrib.contenttypes.fields|<code>GenericForeignKey</code>]], however, it
 
must be restricted to a homogeneous set of results. For example, prefetching
 
objects referenced by a <code>GenericForeignKey</code> is only supported if the query
 
is restricted to one <code>ContentType</code>.
 
  
For example, suppose you have these models:
+
例如,假设您有以下模型:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,476行: 第1,175行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.db import models
+
<syntaxhighlight lang="python">from django.db import models
  
 
class Topping(models.Model):
 
class Topping(models.Model):
第1,486行: 第1,185行:
  
 
     def __str__(self):
 
     def __str__(self):
         return &quot;%s (%s)&quot; % (
+
         return "%s (%s)" % (
 
             self.name,
 
             self.name,
             &quot;, &quot;.join(topping.name for topping in self.toppings.all()),
+
             ", ".join(topping.name for topping in self.toppings.all()),
         )</pre>
+
         )</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
and run:
+
并运行:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,500行: 第1,199行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Pizza.objects.all()
+
<syntaxhighlight lang="python">>>> Pizza.objects.all()
[&quot;Hawaiian (ham, pineapple)&quot;, &quot;Seafood (prawns, smoked salmon)&quot;...</pre>
+
["Hawaiian (ham, pineapple)", "Seafood (prawns, smoked salmon)"...</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The problem with this is that every time <code>Pizza.__str__()</code> asks for
+
问题在于,每次 <code>Pizza.__str__()</code> 请求 <code>self.toppings.all()</code> 时,它都必须查询数据库,因此 <code>Pizza.objects.all()</code> 将对 every[ X165X] 比萨中的项目 <code>QuerySet</code>
<code>self.toppings.all()</code> it has to query the database, so
 
<code>Pizza.objects.all()</code> will run a query on the Toppings table for '''every'''
 
item in the Pizza <code>QuerySet</code>.
 
  
We can reduce to just two queries using <code>prefetch_related</code>:
+
我们可以使用 <code>prefetch_related</code> 减少到两个查询:
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,517行: 第1,213行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Pizza.objects.all().prefetch_related('toppings')</pre>
+
<syntaxhighlight lang="python">>>> Pizza.objects.all().prefetch_related('toppings')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
This implies a <code>self.toppings.all()</code> for each <code>Pizza</code>; now each time
+
这意味着每个 <code>Pizza</code> 都有一个 <code>self.toppings.all()</code>; 现在,每次调用 <code>self.toppings.all()</code> 时,不必去数据库查找项目,它会在预取的 <code>QuerySet</code> 缓存中找到它们,该缓存已填充在单个查询中。
<code>self.toppings.all()</code> is called, instead of having to go to the database for
 
the items, it will find them in a prefetched <code>QuerySet</code> cache that was
 
populated in a single query.
 
  
That is, all the relevant toppings will have been fetched in a single query,
+
也就是说,所有相关的浇头都将在单个查询中被获取,并用于使 <code>QuerySets</code> 具有相关结果的预填充缓存; 这些 <code>QuerySets</code> 然后用于 <code>self.toppings.all()</code> 调用。
and used to make <code>QuerySets</code> that have a pre-filled cache of the relevant
 
results; these <code>QuerySets</code> are then used in the <code>self.toppings.all()</code> calls.
 
  
The additional queries in <code>prefetch_related()</code> are executed after the
+
<code>prefetch_related()</code> 中的附加查询在 <code>QuerySet</code> 开始评估并执行主查询后执行。
<code>QuerySet</code> has begun to be evaluated and the primary query has been executed.
 
  
If you have an iterable of model instances, you can prefetch related attributes
+
如果您有可迭代的模型实例,您可以使用 [[#django.db.models.prefetch_related_objects|prefetch_related_objects()]] 函数预取这些实例上的相关属性。
on those instances using the [[#django.db.models.prefetch_related_objects|<code>prefetch_related_objects()</code>]]
 
function.
 
  
Note that the result cache of the primary <code>QuerySet</code> and all specified related
+
请注意,主 <code>QuerySet</code> 的结果缓存和所有指定的相关对象将被完全加载到内存中。 这改变了 <code>QuerySets</code> 的典型行为,它通常会尽量避免在需要之前将所有对象加载到内存中,即使在数据库中执行了查询之后也是如此。
objects will then be fully loaded into memory. This changes the typical
 
behavior of <code>QuerySets</code>, which normally try to avoid loading all objects into
 
memory before they are needed, even after a query has been executed in the
 
database.
 
  
 
<div class="admonition note">
 
<div class="admonition note">
第1,548行: 第1,232行:
 
注解
 
注解
  
Remember that, as always with <code>QuerySets</code>, any subsequent chained methods
+
请记住,与 <code>QuerySets</code> 一样,任何暗示不同数据库查询的后续链接方法都将忽略先前缓存的结果,并使用新的数据库查询检索数据。 因此,如果您编写以下内容:
which imply a different database query will ignore previously cached
 
results, and retrieve data using a fresh database query. So, if you write
 
the following:
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,557行: 第1,238行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; pizzas = Pizza.objects.prefetch_related('toppings')
+
<syntaxhighlight lang="python">>>> pizzas = Pizza.objects.prefetch_related('toppings')
&gt;&gt;&gt; [list(pizza.toppings.filter(spicy=True)) for pizza in pizzas]</pre>
+
>>> [list(pizza.toppings.filter(spicy=True)) for pizza in pizzas]</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
...then the fact that <code>pizza.toppings.all()</code> has been prefetched will not
+
...那么<code>pizza.toppings.all()</code> 已被预取的事实对您没有帮助。 <code>prefetch_related('toppings')</code> 暗示 <code>pizza.toppings.all()</code>,但 <code>pizza.toppings.filter()</code> 是一个新的不同的查询。 预取缓存在这里无济于事; 事实上,它会损害性能,因为您已经完成了一个您没有使用过的数据库查询。 所以请谨慎使用此功能!
help you. The <code>prefetch_related('toppings')</code> implied
 
<code>pizza.toppings.all()</code>, but <code>pizza.toppings.filter()</code> is a new and
 
different query. The prefetched cache can't help here; in fact it hurts
 
performance, since you have done a database query that you haven't used. So
 
use this feature with caution!
 
  
Also, if you call the database-altering methods
+
此外,如果您调用数据库更改方法 [[../relations#django.db.models.fields.related.RelatedManager|add()]][[../relations#django.db.models.fields.related.RelatedManager|remove()]][[../relations#django.db.models.fields.related.RelatedManager|clear()]] [[../relations#django.db.models.fields.related.RelatedManager|set()]],在 [[../relations#django.db.models.fields.related|相关管理器]] 上,该关系的任何预取缓存都将被清除。
[[../relations#django.db.models.fields.related.RelatedManager|<code>add()</code>]],
 
[[../relations#django.db.models.fields.related.RelatedManager|<code>remove()</code>]],
 
[[../relations#django.db.models.fields.related.RelatedManager|<code>clear()</code>]] or
 
[[../relations#django.db.models.fields.related.RelatedManager|<code>set()</code>]], on
 
[[../relations#django.db.models.fields.related|<code>related managers</code>]],
 
any prefetched cache for the relation will be cleared.
 
  
  
 
</div>
 
</div>
You can also use the normal join syntax to do related fields of related
+
您也可以使用普通的 join 语法来做相关字段的相关字段。 假设我们在上面的例子中有一个额外的模型:
fields. Suppose we have an additional model to the example above:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,587行: 第1,256行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>class Restaurant(models.Model):
+
<syntaxhighlight lang="python">class Restaurant(models.Model):
 
     pizzas = models.ManyToManyField(Pizza, related_name='restaurants')
 
     pizzas = models.ManyToManyField(Pizza, related_name='restaurants')
     best_pizza = models.ForeignKey(Pizza, related_name='championed_by', on_delete=models.CASCADE)</pre>
+
     best_pizza = models.ForeignKey(Pizza, related_name='championed_by', on_delete=models.CASCADE)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The following are all legal:
+
以下都是合法的:
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,600行: 第1,269行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Restaurant.objects.prefetch_related('pizzas__toppings')</pre>
+
<syntaxhighlight lang="python">>>> Restaurant.objects.prefetch_related('pizzas__toppings')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
This will prefetch all pizzas belonging to restaurants, and all toppings
+
这将预取属于餐厅的所有比萨饼,以及属于这些比萨饼的所有配料。 这将导致总共 3 个数据库查询 - 一个用于餐厅,一个用于比萨饼,一个用于浇头。
belonging to those pizzas. This will result in a total of 3 database queries -
 
one for the restaurants, one for the pizzas, and one for the toppings.
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,613行: 第1,280行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Restaurant.objects.prefetch_related('best_pizza__toppings')</pre>
+
<syntaxhighlight lang="python">>>> Restaurant.objects.prefetch_related('best_pizza__toppings')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
This will fetch the best pizza and all the toppings for the best pizza for each
+
这将为每个餐厅获取最好的比萨饼和所有最好的比萨饼的配料。 这将在 3 个数据库查询中完成 - 一个用于餐厅,一个用于“最好的比萨饼”,另一个用于浇头。
restaurant. This will be done in 3 database queries - one for the restaurants,
 
one for the 'best pizzas', and one for the toppings.
 
  
Of course, the <code>best_pizza</code> relationship could also be fetched using
+
当然,也可以使用 <code>select_related</code> 来获取 <code>best_pizza</code> 关系,以将查询计数减少到 2:
<code>select_related</code> to reduce the query count to 2:
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,629行: 第1,293行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Restaurant.objects.select_related('best_pizza').prefetch_related('best_pizza__toppings')</pre>
+
<syntaxhighlight lang="python">>>> Restaurant.objects.select_related('best_pizza').prefetch_related('best_pizza__toppings')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Since the prefetch is executed after the main query (which includes the joins
+
由于预取是在主查询(包括 <code>select_related</code> 所需的连接)之后执行的,因此能够检测到 <code>best_pizza</code> 对象已经被提取,它会跳过再次提取它们.
needed by <code>select_related</code>), it is able to detect that the <code>best_pizza</code>
 
objects have already been fetched, and it will skip fetching them again.
 
  
Chaining <code>prefetch_related</code> calls will accumulate the lookups that are
+
链接 <code>prefetch_related</code> 调用将累积预取的查找。 要清除任何 <code>prefetch_related</code> 行为,请将 <code>None</code> 作为参数传递:
prefetched. To clear any <code>prefetch_related</code> behavior, pass <code>None</code> as a
 
parameter:
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,646行: 第1,306行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; non_prefetched = qs.prefetch_related(None)</pre>
+
<syntaxhighlight lang="python">>>> non_prefetched = qs.prefetch_related(None)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
One difference to note when using <code>prefetch_related</code> is that objects created
+
使用 <code>prefetch_related</code> 时要注意的一个区别是查询创建的对象可以在它们相关的不同对象之间共享,即 单个 Python 模型实例可以出现在返回的对象树中的多个点。 这通常会发生在外键关系中。 通常这种行为不会有问题,而且实际上会节省内存和 CPU 时间。
by a query can be shared between the different objects that they are related to
 
i.e. a single Python model instance can appear at more than one point in the
 
tree of objects that are returned. This will normally happen with foreign key
 
relationships. Typically this behavior will not be a problem, and will in fact
 
save both memory and CPU time.
 
  
While <code>prefetch_related</code> supports prefetching <code>GenericForeignKey</code>
+
虽然 <code>prefetch_related</code> 支持预取 <code>GenericForeignKey</code> 关系,但查询的数量将取决于数据。 由于 <code>GenericForeignKey</code> 可以引用多个表中的数据,因此需要对每个引用的表进行一次查询,而不是对所有项目进行一次查询。 如果尚未提取相关行,则可能会对 <code>ContentType</code> 表进行其他查询。
relationships, the number of queries will depend on the data. Since a
 
<code>GenericForeignKey</code> can reference data in multiple tables, one query per table
 
referenced is needed, rather than one query for all the items. There could be
 
additional queries on the <code>ContentType</code> table if the relevant rows have not
 
already been fetched.
 
  
<code>prefetch_related</code> in most cases will be implemented using an SQL query that
+
<code>prefetch_related</code> 在大多数情况下将使用使用“IN”运算符的 SQL 查询来实现。 这意味着对于大的 <code>QuerySet</code> 可能会生成一个大的“IN”子句,这取决于数据库,在解析或执行 SQL 查询时可能会出现其自身的性能问题。 始终针对您的用例进行分析!
uses the 'IN' operator. This means that for a large <code>QuerySet</code> a large 'IN' clause
 
could be generated, which, depending on the database, might have performance
 
problems of its own when it comes to parsing or executing the SQL query. Always
 
profile for your use case!
 
  
Note that if you use <code>iterator()</code> to run the query, <code>prefetch_related()</code>
+
请注意,如果您使用 <code>iterator()</code> 运行查询,<code>prefetch_related()</code> 调用将被忽略,因为这两个优化一起使用没有意义。
calls will be ignored since these two optimizations do not make sense together.
 
  
You can use the [[#django.db.models.Prefetch|<code>Prefetch</code>]] object to further control
+
您可以使用 [[#django.db.models.Prefetch|Prefetch]] 对象进一步控制预取操作。
the prefetch operation.
 
  
In its simplest form <code>Prefetch</code> is equivalent to the traditional string based
+
最简单的形式 <code>Prefetch</code> 相当于传统的基于字符串的查找:
lookups:
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,684行: 第1,327行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; from django.db.models import Prefetch
+
<syntaxhighlight lang="python">>>> from django.db.models import Prefetch
&gt;&gt;&gt; Restaurant.objects.prefetch_related(Prefetch('pizzas__toppings'))</pre>
+
>>> Restaurant.objects.prefetch_related(Prefetch('pizzas__toppings'))</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
You can provide a custom queryset with the optional <code>queryset</code> argument.
+
您可以使用可选的 <code>queryset</code> 参数提供自定义查询集。 这可用于更改查询集的默认顺序:
This can be used to change the default ordering of the queryset:
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,697行: 第1,339行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Restaurant.objects.prefetch_related(
+
<syntaxhighlight lang="python">>>> Restaurant.objects.prefetch_related(
...    Prefetch('pizzas__toppings', queryset=Toppings.objects.order_by('name')))</pre>
+
...    Prefetch('pizzas__toppings', queryset=Toppings.objects.order_by('name')))</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Or to call [[#django.db.models.query.QuerySet.select_related|<code>select_related()</code>]] when
+
或者在适用时调用 [[#django.db.models.query.QuerySet.select_related|select_related()]] 以进一步减少查询数量:
applicable to reduce the number of queries even further:
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,710行: 第1,351行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Pizza.objects.prefetch_related(
+
<syntaxhighlight lang="python">>>> Pizza.objects.prefetch_related(
...    Prefetch('restaurants', queryset=Restaurant.objects.select_related('best_pizza')))</pre>
+
...    Prefetch('restaurants', queryset=Restaurant.objects.select_related('best_pizza')))</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
You can also assign the prefetched result to a custom attribute with the optional
+
您还可以使用可选的 <code>to_attr</code> 参数将预取结果分配给自定义属性。 结果将直接存储在列表中。
<code>to_attr</code> argument. The result will be stored directly in a list.
 
  
This allows prefetching the same relation multiple times with a different
+
这允许使用不同的 <code>QuerySet</code> 多次预取相同的关系; 例如:
<code>QuerySet</code>; for instance:
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,726行: 第1,365行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; vegetarian_pizzas = Pizza.objects.filter(vegetarian=True)
+
<syntaxhighlight lang="python">>>> vegetarian_pizzas = Pizza.objects.filter(vegetarian=True)
&gt;&gt;&gt; Restaurant.objects.prefetch_related(
+
>>> Restaurant.objects.prefetch_related(
 
...    Prefetch('pizzas', to_attr='menu'),
 
...    Prefetch('pizzas', to_attr='menu'),
...    Prefetch('pizzas', queryset=vegetarian_pizzas, to_attr='vegetarian_menu'))</pre>
+
...    Prefetch('pizzas', queryset=vegetarian_pizzas, to_attr='vegetarian_menu'))</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Lookups created with custom <code>to_attr</code> can still be traversed as usual by other
+
使用自定义 <code>to_attr</code> 创建的查找仍然可以像往常一样被其他查找遍历:
lookups:
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,741行: 第1,379行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; vegetarian_pizzas = Pizza.objects.filter(vegetarian=True)
+
<syntaxhighlight lang="python">>>> vegetarian_pizzas = Pizza.objects.filter(vegetarian=True)
&gt;&gt;&gt; Restaurant.objects.prefetch_related(
+
>>> Restaurant.objects.prefetch_related(
 
...    Prefetch('pizzas', queryset=vegetarian_pizzas, to_attr='vegetarian_menu'),
 
...    Prefetch('pizzas', queryset=vegetarian_pizzas, to_attr='vegetarian_menu'),
...    'vegetarian_menu__toppings')</pre>
+
...    'vegetarian_menu__toppings')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Using <code>to_attr</code> is recommended when filtering down the prefetch result as it is
+
在过滤预取结果时建议使用 <code>to_attr</code>,因为它比将过滤结果存储在相关管理器的缓存中更不模糊:
less ambiguous than storing a filtered result in the related manager's cache:
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,756行: 第1,393行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; queryset = Pizza.objects.filter(vegetarian=True)
+
<syntaxhighlight lang="python">>>> queryset = Pizza.objects.filter(vegetarian=True)
&gt;&gt;&gt;
+
>>>
&gt;&gt;&gt; # Recommended:
+
>>> # Recommended:
&gt;&gt;&gt; restaurants = Restaurant.objects.prefetch_related(
+
>>> restaurants = Restaurant.objects.prefetch_related(
 
...    Prefetch('pizzas', queryset=queryset, to_attr='vegetarian_pizzas'))
 
...    Prefetch('pizzas', queryset=queryset, to_attr='vegetarian_pizzas'))
&gt;&gt;&gt; vegetarian_pizzas = restaurants[0].vegetarian_pizzas
+
>>> vegetarian_pizzas = restaurants[0].vegetarian_pizzas
&gt;&gt;&gt;
+
>>>
&gt;&gt;&gt; # Not recommended:
+
>>> # Not recommended:
&gt;&gt;&gt; restaurants = Restaurant.objects.prefetch_related(
+
>>> restaurants = Restaurant.objects.prefetch_related(
 
...    Prefetch('pizzas', queryset=queryset))
 
...    Prefetch('pizzas', queryset=queryset))
&gt;&gt;&gt; vegetarian_pizzas = restaurants[0].pizzas.all()</pre>
+
>>> vegetarian_pizzas = restaurants[0].pizzas.all()</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Custom prefetching also works with single related relations like
+
自定义预取也适用于单个相关关系,如前向 <code>ForeignKey</code> <code>OneToOneField</code>。 通常,您需要将 [[#django.db.models.query.QuerySet.select_related|select_related()]] 用于这些关系,但在许多情况下,使用自定义 <code>QuerySet</code> 进行预取很有用:
forward <code>ForeignKey</code> or <code>OneToOneField</code>. Generally you'll want to use
 
[[#django.db.models.query.QuerySet.select_related|<code>select_related()</code>]] for these relations, but there are a number of cases
 
where prefetching with a custom <code>QuerySet</code> is useful:
 
  
 
<ul>
 
<ul>
<li><p>You want to use a <code>QuerySet</code> that performs further prefetching
+
<li><p>您想使用 <code>QuerySet</code> 对相关模型执行进一步预取。</p></li>
on related models.</p></li>
+
<li><p>你想只预取相关对象的一个子集。</p></li>
<li><p>You want to prefetch only a subset of the related objects.</p></li>
+
<li><p>您想使用性能优化技术,如 [[#django.db.models.query.QuerySet.defer|延迟字段]] </p>
<li><p>You want to use performance optimization techniques like
 
[[#django.db.models.query.QuerySet.defer|<code>deferred fields</code>]]:</p>
 
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; queryset = Pizza.objects.only('name')
+
<syntaxhighlight lang="python">>>> queryset = Pizza.objects.only('name')
&gt;&gt;&gt;
+
>>>
&gt;&gt;&gt; restaurants = Restaurant.objects.prefetch_related(
+
>>> restaurants = Restaurant.objects.prefetch_related(
...    Prefetch('best_pizza', queryset=queryset))</pre>
+
...    Prefetch('best_pizza', queryset=queryset))</syntaxhighlight>
  
 
</div>
 
</div>
第1,799行: 第1,431行:
 
注解
 
注解
  
The ordering of lookups matters.
+
查询的顺序很重要。
  
Take the following examples:
+
下面举例说明:
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,807行: 第1,439行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; prefetch_related('pizzas__toppings', 'pizzas')</pre>
+
<syntaxhighlight lang="python">>>> prefetch_related('pizzas__toppings', 'pizzas')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
This works even though it's unordered because <code>'pizzas__toppings'</code>
+
即使它是无序的,这也有效,因为 <code>'pizzas__toppings'</code> 已经包含所有需要的信息,因此第二个参数 <code>'pizzas'</code> 实际上是多余的。
already contains all the needed information, therefore the second argument
 
<code>'pizzas'</code> is actually redundant.
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,820行: 第1,450行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; prefetch_related('pizzas__toppings', Prefetch('pizzas', queryset=Pizza.objects.all()))</pre>
+
<syntaxhighlight lang="python">>>> prefetch_related('pizzas__toppings', Prefetch('pizzas', queryset=Pizza.objects.all()))</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
This will raise a <code>ValueError</code> because of the attempt to redefine the
+
由于尝试重新定义先前看到的查找的查询集,这将引发 <code>ValueError</code>。 请注意,作为 <code>'pizzas__toppings'</code> 查找的一部分,创建了一个隐式查询集来遍历 <code>'pizzas'</code>
queryset of a previously seen lookup. Note that an implicit queryset was
 
created to traverse <code>'pizzas'</code> as part of the <code>'pizzas__toppings'</code>
 
lookup.
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,834行: 第1,461行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; prefetch_related('pizza_list__toppings', Prefetch('pizzas', to_attr='pizza_list'))</pre>
+
<syntaxhighlight lang="python">>>> prefetch_related('pizza_list__toppings', Prefetch('pizzas', to_attr='pizza_list'))</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
This will trigger an <code>AttributeError</code> because <code>'pizza_list'</code> doesn't exist yet
+
这将触发 <code>AttributeError</code>,因为在处理 <code>'pizza_list__toppings'</code> <code>'pizza_list'</code> 还不存在。
when <code>'pizza_list__toppings'</code> is being processed.
 
  
This consideration is not limited to the use of <code>Prefetch</code> objects. Some
+
这种考虑不限于使用 <code>Prefetch</code> 对象。 一些高级技术可能要求以特定顺序执行查找以避免创建额外的查询; 因此,建议始终谨慎地对 <code>prefetch_related</code> 参数进行排序。
advanced techniques may require that the lookups be performed in a
 
specific order to avoid creating extra queries; therefore it's recommended
 
to always carefully order <code>prefetch_related</code> arguments.
 
  
  
第1,853行: 第1,476行:
 
<div id="extra" class="section">
 
<div id="extra" class="section">
  
==== <code>extra()</code> ====
+
==== extra() ====
  
; <code>extra</code><span class="sig-paren">(</span>''<span class="n">select</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">where</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">params</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">tables</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">order_by</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">select_params</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">extra</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">select</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">where</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">params</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">tables</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">order_by</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">select_params</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Sometimes, the Django query syntax by itself can't easily express a complex
+
有时,Django 查询语法本身无法轻松表达复杂的 <code>WHERE</code> 子句。 对于这些边缘情况,Django 提供了 <code>extra()</code> <code>QuerySet</code> 修饰符——一个钩子,用于将特定子句注入由 <code>QuerySet</code> 生成的 SQL。
<code>WHERE</code> clause. For these edge cases, Django provides the <code>extra()</code>
 
<code>QuerySet</code> modifier — a hook for injecting specific clauses into the SQL
 
generated by a <code>QuerySet</code>.
 
  
 
<div class="admonition-use-this-method-as-a-last-resort admonition">
 
<div class="admonition-use-this-method-as-a-last-resort admonition">
  
Use this method as a last resort
+
在万不得已的情况下使用这种方法
  
This is an old API that we aim to deprecate at some point in the future.
+
这是一个旧的 API,我们的目标是在未来的某个时候弃用。 仅当您无法使用其他查询集方法表达查询时才使用它。 如果您确实需要使用它,请使用 [https://code.djangoproject.com/query?status=assigned&status=new&keywords=~QuerySet.extra QuerySet.extra 关键字] 与您的用例一起 [https://code.djangoproject.com/newticket 提交票证] (请先检查现有票证列表),以便我们可以增强QuerySet API 允许删除 <code>extra()</code>。 我们不再改进或修复此方法的错误。
Use it only if you cannot express your query using other queryset methods.
 
If you do need to use it, please [https://code.djangoproject.com/newticket file a ticket] using the [https://code.djangoproject.com/query?status=assigned&status=new&keywords=~QuerySet.extra 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 <code>extra()</code>. We are
 
no longer improving or fixing bugs for this method.
 
  
For example, this use of <code>extra()</code>:
+
例如,<code>extra()</code> 的这种用法:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,881行: 第1,495行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; qs.extra(
+
<syntaxhighlight lang="python">>>> qs.extra(
...    select={'val': &quot;select col from sometable where othercol = %s&quot;},
+
...    select={'val': "select col from sometable where othercol = %s"},
 
...    select_params=(someparam,),
 
...    select_params=(someparam,),
... )</pre>
+
... )</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
相当于:
+
相当于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,895行: 第1,509行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; qs.annotate(val=RawSQL(&quot;select col from sometable where othercol = %s&quot;, (someparam,)))</pre>
+
<syntaxhighlight lang="python">>>> qs.annotate(val=RawSQL("select col from sometable where othercol = %s", (someparam,)))</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The main benefit of using [[../expressions#django.db.models.expressions|<code>RawSQL</code>]] is
+
使用 [[../expressions#django.db.models.expressions|RawSQL]] 的主要好处是您可以根据需要设置 <code>output_field</code>。 主要的缺点是,如果您在原始 SQL 中引用查询集的某个表别名,那么 Django 可能会更改该别名(例如,当查询集用作另一个查询中的子查询时)。
that you can set <code>output_field</code> 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).
 
  
  
第1,912行: 第1,522行:
 
警告
 
警告
  
You should be very careful whenever you use <code>extra()</code>. Every time you use
+
使用 <code>extra()</code> 时应该非常小心。 每次使用它时,都应该使用 <code>params</code> 对用户可以控制的任何参数进行转义,以防止 SQL 注入攻击。
it, you should escape any parameters that the user can control by using
 
<code>params</code> in order to protect against SQL injection attacks.
 
  
You also must not quote placeholders in the SQL string. This example is
+
您也不得在 SQL 字符串中引用占位符。 由于 <code>%s</code> 周围的引号,此示例容易受到 SQL 注入攻击:
vulnerable to SQL injection because of the quotes around <code>%s</code>:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,923行: 第1,530行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&quot;select col from sometable where othercol = '%s'&quot; # unsafe!</pre>
+
<syntaxhighlight lang="python">"select col from sometable where othercol = '%s'" # unsafe!</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
You can read more about how Django's [[../../../topics/security#sql-injection-protection|<span class="std std-ref">SQL injection protection</span>]] works.
+
您可以阅读有关 Django [[../../../topics/security#sql-injection-protection|SQL 注入保护]] 工作原理的更多信息。
  
  
 
</div>
 
</div>
By definition, these extra lookups may not be portable to different database
+
根据定义,这些额外的查找可能无法移植到不同的数据库引擎(因为您明确地编写 SQL 代码)并且违反了 DRY 原则,因此您应该尽可能避免它们。
engines (because you're explicitly writing SQL code) and violate the DRY
 
principle, so you should avoid them if possible.
 
  
Specify one or more of <code>params</code>, <code>select</code>, <code>where</code> or <code>tables</code>. None
+
指定 <code>params</code><code>select</code><code>where</code> <code>tables</code> 中的一个或多个。 不需要任何参数,但您应该至少使用其中之一。
of the arguments is required, but you should use at least one of them.
 
  
 
<ul>
 
<ul>
 
<li><p><code>select</code></p>
 
<li><p><code>select</code></p>
<p>The <code>select</code> argument lets you put extra fields in the <code>SELECT</code>
+
<p><code>select</code> 参数允许您在 <code>SELECT</code> 子句中放置额外的字段。 它应该是一个将属性名称映射到 SQL 子句以用于计算该属性的字典。</p>
clause. It should be a dictionary mapping attribute names to SQL
+
<p>例子:</p>
clauses to use to calculate that attribute.</p>
 
<p>举例:</p>
 
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.extra(select={'is_recent': &quot;pub_date &gt; '2006-01-01'&quot;})</pre>
+
<syntaxhighlight lang="python">Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>As a result, each <code>Entry</code> object will have an extra attribute,
+
<p>因此,每个 <code>Entry</code> 对象都会有一个额外的属性 <code>is_recent</code>,这是一个布尔值,表示条目的 <code>pub_date</code> 是否大于 Jan。 1, 2006.</p>
<code>is_recent</code>, a boolean representing whether the entry's <code>pub_date</code>
+
<p>Django 将给定的 SQL 片段直接插入到 <code>SELECT</code> 语句中,因此上述示例的结果 SQL 将类似于:</p>
is greater than Jan. 1, 2006.</p>
 
<p>Django inserts the given SQL snippet directly into the <code>SELECT</code>
 
statement, so the resulting SQL of the above example would be something
 
like:</p>
 
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT blog_entry.*, (pub_date &gt; '2006-01-01') AS is_recent
+
<syntaxhighlight lang="python">SELECT blog_entry.*, (pub_date > '2006-01-01') AS is_recent
FROM blog_entry;</pre>
+
FROM blog_entry;</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>The next example is more advanced; it does a subquery to give each
+
<p>下一个例子更高级; 它执行一个子查询,为每个结果 <code>Blog</code> 对象提供一个 <code>entry_count</code> 属性,关联 <code>Entry</code> 对象的整数计数:</p>
resulting <code>Blog</code> object an <code>entry_count</code> attribute, an integer count
 
of associated <code>Entry</code> objects:</p>
 
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Blog.objects.extra(
+
<syntaxhighlight lang="python">Blog.objects.extra(
 
     select={
 
     select={
 
         'entry_count': 'SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id'
 
         'entry_count': 'SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id'
 
     },
 
     },
)</pre>
+
)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>In this particular case, we're exploiting the fact that the query will
+
<p>在这种特殊情况下,我们利用查询已经在其 <code>FROM</code> 子句中包含 <code>blog_blog</code> 表的事实。</p>
already contain the <code>blog_blog</code> table in its <code>FROM</code> clause.</p>
+
<p>上述示例的结果 SQL 将是:</p>
<p>上面例子最终的SQL是:</p>
 
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT blog_blog.*, (SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id) AS entry_count
+
<syntaxhighlight lang="python">SELECT blog_blog.*, (SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id) AS entry_count
FROM blog_blog;</pre>
+
FROM blog_blog;</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>Note that the parentheses required by most database engines around
+
<p>请注意,在 Django <code>select</code> 子句中,大多数数据库引擎所需的围绕子查询的括号不是必需的。 另请注意,某些数据库后端(例如某些 MySQL 版本)不支持子查询。</p>
subqueries are not required in Django's <code>select</code> clauses. Also note
+
<p>在极少数情况下,您可能希望将参数传递给 <code>extra(select=...)</code> 中的 SQL 片段。 为此,请使用 <code>select_params</code> 参数。 由于 <code>select_params</code> 是一个序列,而 <code>select</code> 属性是一个字典,因此需要小心谨慎,以便参数与额外的选择片段正确匹配。 在这种情况下,您应该对 <code>select</code> 值使用 <code>collections.OrderedDict</code>,而不仅仅是普通的 Python 字典。</p>
that some database backends, such as some MySQL versions, don't support
+
<p>这将起作用,例如:</p>
subqueries.</p>
 
<p>In some rare cases, you might wish to pass parameters to the SQL
 
fragments in <code>extra(select=...)</code>. For this purpose, use the
 
<code>select_params</code> parameter. Since <code>select_params</code> is a sequence and
 
the <code>select</code> attribute is a dictionary, some care is required so that
 
the parameters are matched up correctly with the extra select pieces.
 
In this situation, you should use a <code>collections.OrderedDict</code> for
 
the <code>select</code> value, not just a normal Python dictionary.</p>
 
<p>This will work, for example:</p>
 
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Blog.objects.extra(
+
<syntaxhighlight lang="python">Blog.objects.extra(
 
     select=OrderedDict([('a', '%s'), ('b', '%s')]),
 
     select=OrderedDict([('a', '%s'), ('b', '%s')]),
     select_params=('one', 'two'))</pre>
+
     select_params=('one', 'two'))</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>If you need to use a literal <code>%s</code> inside your select string, use
+
<p>如果需要在选择字符串中使用文字 <code>%s</code>,请使用序列 <code>%%s</code></p></li>
the sequence <code>%%s</code>.</p></li>
 
 
<li><p><code>where</code> / <code>tables</code></p>
 
<li><p><code>where</code> / <code>tables</code></p>
<p>You can define explicit SQL <code>WHERE</code> clauses — perhaps to perform
+
<p>您可以使用 <code>where</code> 定义显式 SQL <code>WHERE</code> 子句——也许是为了执行非显式连接。 您可以使用 <code>tables</code> 手动向 SQL <code>FROM</code> 子句添加表。</p>
non-explicit joins — by using <code>where</code>. You can manually add tables to
+
<p><code>where</code> <code>tables</code> 都采用字符串列表。 所有 <code>where</code> 参数都与任何其他搜索条件进行“与”运算。</p>
the SQL <code>FROM</code> clause by using <code>tables</code>.</p>
+
<p>例子:</p>
<p><code>where</code> and <code>tables</code> both take a list of strings. All <code>where</code>
 
parameters are &quot;AND&quot;ed to any other search criteria.</p>
 
<p>举例:</p>
 
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.extra(where=[&quot;foo='a' OR bar = 'a'&quot;, &quot;baz = 'a'&quot;])</pre>
+
<syntaxhighlight lang="python">Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>...translates (roughly) into the following SQL:</p>
+
<p>...翻译(大致)为以下 SQL:</p>
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT * FROM blog_entry WHERE (foo='a' OR bar='a') AND (baz='a')</pre>
+
<syntaxhighlight lang="python">SELECT * FROM blog_entry WHERE (foo='a' OR bar='a') AND (baz='a')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>Be careful when using the <code>tables</code> parameter if you're specifying
+
<p>如果您指定的表已在查询中使用,则在使用 <code>tables</code> 参数时要小心。 当您通过 <code>tables</code> 参数添加额外的表时,Django 假定您希望该表包含额外的时间,如果它已经包含在内。 这就产生了一个问题,因为表名将被赋予一个别名。 如果一个表在 SQL 语句中多次出现,则第二次和后续出现必须使用别名,以便数据库可以区分它们。 如果您指的是在额外 <code>where</code> 参数中添加的额外表,这将导致错误。</p>
tables that are already used in the query. When you add extra tables
+
<p>通常,您只会添加尚未出现在查询中的额外表。 但是,如果确实发生了上述情况,则有几种解决方案。 首先,看看您是否可以不包含额外的表并使用查询中已有的表。 如果这是不可能的,请将您的 <code>extra()</code> 调用放在查询集构造的前面,以便您的表是该表的第一次使用。 最后,如果所有其他方法都失败了,请查看生成的查询并重写您的 <code>where</code> 添加以使用为额外表提供的别名。 每次以相同的方式构造查询集时,别名都将相同,因此您可以依赖别名不会更改。</p></li>
via the <code>tables</code> parameter, Django assumes you want that table
 
included an extra time, if it is already included. That creates a
 
problem, since the table name will then be given an alias. If a table
 
appears multiple times in an SQL statement, the second and subsequent
 
occurrences must use aliases so the database can tell them apart. If
 
you're referring to the extra table you added in the extra <code>where</code>
 
parameter this is going to cause errors.</p>
 
<p>Normally you'll only be adding extra tables that don't already appear
 
in the query. However, if the case outlined above does occur, there are
 
a few solutions. First, see if you can get by without including the
 
extra table and use the one already in the query. If that isn't
 
possible, put your <code>extra()</code> call at the front of the queryset
 
construction so that your table is the first use of that table.
 
Finally, if all else fails, look at the query produced and rewrite your
 
<code>where</code> addition to use the alias given to your extra table. The
 
alias will be the same each time you construct the queryset in the same
 
way, so you can rely upon the alias name to not change.</p></li>
 
 
<li><p><code>order_by</code></p>
 
<li><p><code>order_by</code></p>
<p>If you need to order the resulting queryset using some of the new
+
<p>如果您需要使用通过 <code>extra()</code> 包含的一些新字段或表对结果查询集进行排序,请使用 <code>order_by</code> 参数到 <code>extra()</code> 并传入一系列字符串。 这些字符串应该是模型字段(如查询集上的正常 [[#django.db.models.query.QuerySet.order_by|order_by()]] 方法),形式为 <code>table_name.column_name</code> 或您在 [ 中指定的列的别名X181X] 参数设置为 <code>extra()</code></p>
fields or tables you have included via <code>extra()</code> use the <code>order_by</code>
+
<p>例如:</p>
parameter to <code>extra()</code> and pass in a sequence of strings. These
 
strings should either be model fields (as in the normal
 
[[#django.db.models.query.QuerySet.order_by|<code>order_by()</code>]] method on querysets), of the form
 
<code>table_name.column_name</code> or an alias for a column that you specified
 
in the <code>select</code> parameter to <code>extra()</code>.</p>
 
<p>例子:</p>
 
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>q = Entry.objects.extra(select={'is_recent': &quot;pub_date &gt; '2006-01-01'&quot;})
+
<syntaxhighlight lang="python">q = Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})
q = q.extra(order_by = ['-is_recent'])</pre>
+
q = q.extra(order_by = ['-is_recent'])</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>This would sort all the items for which <code>is_recent</code> is true to the
+
<p>这会将 <code>is_recent</code> 为真的所有项目排序到结果集的前面(<code>True</code> 按降序排列在 <code>False</code> 之前)。</p>
front of the result set (<code>True</code> sorts before <code>False</code> in a
+
<p>顺便说一下,这表明您可以多次调用 <code>extra()</code> 并且它会按照您的预期运行(每次添加新约束)。</p></li>
descending ordering).</p>
 
<p>This shows, by the way, that you can make multiple calls to <code>extra()</code>
 
and it will behave as you expect (adding new constraints each time).</p></li>
 
 
<li><p><code>params</code></p>
 
<li><p><code>params</code></p>
<p>The <code>where</code> parameter described above may use standard Python
+
<p>上述 <code>where</code> 参数可以使用标准 Python 数据库字符串占位符 — <code>'%s'</code> 来指示数据库引擎应自动引用的参数。 <code>params</code> 参数是要替换的任何额外参数的列表。</p>
database string placeholders — <code>'%s'</code> to indicate parameters the
+
<p>例子:</p>
database engine should automatically quote. The <code>params</code> argument is
 
a list of any extra parameters to be substituted.</p>
 
<p>举例:</p>
 
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.extra(where=['headline=%s'], params=['Lennon'])</pre>
+
<syntaxhighlight lang="python">Entry.objects.extra(where=['headline=%s'], params=['Lennon'])</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>Always use <code>params</code> instead of embedding values directly into
+
<p>始终使用 <code>params</code> 而不是直接将值嵌入到 <code>where</code> 中,因为 <code>params</code> 将确保根据您的特定后端正确引用值。 例如,引号将被正确转义。</p>
<code>where</code> because <code>params</code> will ensure values are quoted correctly
+
<p>坏的:</p>
according to your particular backend. For example, quotes will be
 
escaped correctly.</p>
 
<p>Bad:</p>
 
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.extra(where=[&quot;headline='Lennon'&quot;])</pre>
+
<syntaxhighlight lang="python">Entry.objects.extra(where=["headline='Lennon'"])</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>Good:</p>
+
<p>好的:</p>
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.extra(where=['headline=%s'], params=['Lennon'])</pre>
+
<syntaxhighlight lang="python">Entry.objects.extra(where=['headline=%s'], params=['Lennon'])</syntaxhighlight>
  
 
</div>
 
</div>
第2,137行: 第1,687行:
 
警告
 
警告
  
若你在 MySQL 上执行查询,至于其无声的强制类型可能会弄混类型时导致不可预料的后果。若你用一个整数值查询一个字符串列,MySQL 会执行比较前将表中所有数据强制转为整数。例如,若数据表包含的值有 <code>'abc'</code> <code>'def'</code>,而查询语句为 <code>WHERE mycolumn=0</code>,这两行都会匹配上。要避免这种情况,在将值传给查询语句前进行合适的类型转换。
+
如果您在 MySQL 上执行查询,请注意 MySQL 的静默类型强制在混合类型时可能会导致意外结果。 如果查询字符串类型的列,但使用的是整数值,MySQL 会在执行比较之前将表中所有值的类型强制为整数。 例如,如果您的表包含值 <code>'abc'</code><code>'def'</code> 并且您查询 <code>WHERE mycolumn=0</code>,则两行都将匹配。 为防止出现这种情况,请在查询中使用该值之前执行正确的类型转换。
  
  
第2,145行: 第1,695行:
 
<div id="defer" class="section">
 
<div id="defer" class="section">
  
==== <code>defer()</code> ====
+
==== defer() ====
  
; <code>defer</code><span class="sig-paren">(</span>''<span class="o">*</span><span class="n">fields</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">defer</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">fields</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
In some complex data-modeling situations, your models might contain a lot of
+
在某些复杂的数据建模情况下,您的模型可能包含大量字段,其中一些字段可能包含大量数据(例如,文本字段),或者需要进行昂贵的处理才能将它们转换为 Python 对象。 如果您在最初获取数据时不知道是否需要这些特定字段的情况下使用查询集的结果,您可以告诉 Django 不要从数据库中检索它们。
fields, some of which could contain a lot of data (for example, text fields),
 
or require expensive processing to convert them to Python objects. If you are
 
using the results of a queryset in some situation where you don't know
 
if you need those particular fields when you initially fetch the data, you can
 
tell Django not to retrieve them from the database.
 
  
This is done by passing the names of the fields to not load to <code>defer()</code>:
+
这是通过将字段的名称传递给 <code>defer()</code> 来完成的:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,163行: 第1,708行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.defer(&quot;headline&quot;, &quot;body&quot;)</pre>
+
<syntaxhighlight lang="python">Entry.objects.defer("headline", "body")</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
A queryset that has deferred fields will still return model instances. Each
+
具有延迟字段的查询集仍将返回模型实例。 如果您访问该字段(一次一个,而不是一次访问所有延迟字段),将从数据库中检索每个延迟字段。
deferred field will be retrieved from the database if you access that field
 
(one at a time, not all the deferred fields at once).
 
  
You can make multiple calls to <code>defer()</code>. Each call adds new fields to the
+
您可以多次呼叫 <code>defer()</code>。 每次调用都会向延迟集合添加新字段:
deferred set:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,179行: 第1,721行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre># Defers both the body and headline fields.
+
<syntaxhighlight lang="python"># Defers both the body and headline fields.
Entry.objects.defer(&quot;body&quot;).filter(rating=5).defer(&quot;headline&quot;)</pre>
+
Entry.objects.defer("body").filter(rating=5).defer("headline")</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The order in which fields are added to the deferred set does not matter.
+
将字段添加到延迟集中的顺序无关紧要。 使用已被延迟的字段名称调用 <code>defer()</code> 是无害的(该字段仍将被延迟)。
Calling <code>defer()</code> with a field name that has already been deferred is
 
harmless (the field will still be deferred).
 
  
You can defer loading of fields in related models (if the related models are
+
您可以通过使用标准双下划线符号分隔相关字段来延迟加载相关模型中的字段(如果相关模型通过 [[#django.db.models.query.QuerySet.select_related|select_related()]] 加载):
loading via [[#django.db.models.query.QuerySet.select_related|<code>select_related()</code>]]) by using the standard double-underscore
 
notation to separate related fields:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,197行: 第1,735行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Blog.objects.select_related().defer(&quot;entry__headline&quot;, &quot;entry__body&quot;)</pre>
+
<syntaxhighlight lang="python">Blog.objects.select_related().defer("entry__headline", "entry__body")</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
If you want to clear the set of deferred fields, pass <code>None</code> as a parameter
+
如果要清除延迟字段集,请将 <code>None</code> 作为参数传递给 <code>defer()</code>
to <code>defer()</code>:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,209行: 第1,746行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre># Load all fields immediately.
+
<syntaxhighlight lang="python"># Load all fields immediately.
my_queryset.defer(None)</pre>
+
my_queryset.defer(None)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Some fields in a model won't be deferred, even if you ask for them. You can
+
模型中的某些字段不会被延迟,即使您要求它们。 你永远不能推迟主键的加载。 如果您使用 [[#django.db.models.query.QuerySet.select_related|select_related()]] 检索相关模型,则不应推迟从主模型连接到相关模型的字段的加载,否则会导致错误。
never defer the loading of the primary key. If you are using
 
[[#django.db.models.query.QuerySet.select_related|<code>select_related()</code>]] to retrieve related models, you shouldn't defer the
 
loading of the field that connects from the primary model to the related
 
one, doing so will result in an error.
 
  
 
<div class="admonition note">
 
<div class="admonition note">
第2,225行: 第1,758行:
 
注解
 
注解
  
The <code>defer()</code> method (and its cousin, [[#django.db.models.query.QuerySet.only|<code>only()</code>]], below) are only for
+
<code>defer()</code> 方法(及其表亲 [[#django.db.models.query.QuerySet.only|only()]],如下)仅适用于高级用例。 当您仔细分析查询并准确了解 '''' 您需要什么信息并测量返回您需要的字段与模型的完整字段集之间的差异时,它们提供了一种优化。
advanced use-cases. They provide an optimization for when you have analyzed
 
your queries closely and understand ''exactly'' what information you need and
 
have measured that the difference between returning the fields you need and
 
the full set of fields for the model will be significant.
 
  
Even if you think you are in the advanced use-case situation, '''only use
+
即使您认为您处于高级用例情况, '''仅在您无法在查询集加载时确定是否需要额外字段时才使用 defer()''' 。 如果您经常加载和使用数据的特定子集,您可以做出的最佳选择是规范化模型并将未加载的数据放入单独的模型(和数据库表)中。 如果列 ''must'' 出于某种原因保留在一个表中,请使用 <code>Meta.managed = False</code> 创建一个模型(请参阅 [[../options#django.db.models.Options|managed 属性]] 文档)只包含您通常需要的字段加载并使用您可能会调用 <code>defer()</code> 的地方。 这使您的代码对读者更加明确,速度稍快,并且在 Python 进程中消耗的内存更少。
defer() when you cannot, at queryset load time, determine if you will need
 
the extra fields or not'''. If you are frequently loading and using a
 
particular subset of your data, the best choice you can make is to
 
normalize your models and put the non-loaded data into a separate model
 
(and database table). If the columns ''must'' stay in the one table for some
 
reason, create a model with <code>Meta.managed = False</code> (see the
 
[[../options#django.db.models.Options|<code>managed attribute</code>]] documentation)
 
containing just the fields you normally need to load and use that where you
 
might otherwise call <code>defer()</code>. This makes your code more explicit to the
 
reader, is slightly faster and consumes a little less memory in the Python
 
process.
 
  
For example, both of these models use the same underlying database table:
+
例如,这两个模型都使用相同的底层数据库表:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,250行: 第1,768行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>class CommonlyUsedModel(models.Model):
+
<syntaxhighlight lang="python">class CommonlyUsedModel(models.Model):
 
     f1 = models.CharField(max_length=10)
 
     f1 = models.CharField(max_length=10)
  
第2,266行: 第1,784行:
 
# Two equivalent QuerySets:
 
# Two equivalent QuerySets:
 
CommonlyUsedModel.objects.all()
 
CommonlyUsedModel.objects.all()
ManagedModel.objects.all().defer('f2')</pre>
+
ManagedModel.objects.all().defer('f2')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
If many fields need to be duplicated in the unmanaged model, it may be best
+
如果很多字段需要在非托管模型中重复,最好的办法是创建一个共享字段的抽象模型,然后让非托管模型和托管模型从抽象模型中继承。
to create an abstract model with the shared fields and then have the
 
unmanaged and managed models inherit from the abstract model.
 
  
  
第2,281行: 第1,797行:
 
注解
 
注解
  
When calling [[../instances#django.db.models.Model|<code>save()</code>]] for instances with
+
当为具有延迟字段的实例调用 [[../instances#django.db.models.Model|save()]] 时,只会保存加载的字段。 有关更多详细信息,请参阅 [[../instances#django.db.models.Model|save()]]
deferred fields, only the loaded fields will be saved. See
 
[[../instances#django.db.models.Model|<code>save()</code>]] for more details.
 
  
  
第2,291行: 第1,805行:
 
<div id="only" class="section">
 
<div id="only" class="section">
  
==== <code>only()</code> ====
+
==== only() ====
  
; <code>only</code><span class="sig-paren">(</span>''<span class="o">*</span><span class="n">fields</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">only</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">fields</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
The <code>only()</code> method is more or less the opposite of [[#django.db.models.query.QuerySet.defer|<code>defer()</code>]]. You call
+
<code>only()</code> 方法或多或少与 [[#django.db.models.query.QuerySet.defer|defer()]] 相反。 您可以使用在检索模型时应延迟 ''而非'' 的字段调用它。 如果您的模型几乎所有字段都需要延迟,则使用 <code>only()</code> 指定补充字段集可以简化代码。
it with the fields that should ''not'' be deferred when retrieving a model. If
 
you have a model where almost all the fields need to be deferred, using
 
<code>only()</code> to specify the complementary set of fields can result in simpler
 
code.
 
  
Suppose you have a model with fields <code>name</code>, <code>age</code> and <code>biography</code>. The
+
假设您有一个包含字段 <code>name</code><code>age</code> <code>biography</code> 的模型。 以下两个查询集在延迟字段方面是相同的:
following two querysets are the same, in terms of deferred fields:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,309行: 第1,818行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Person.objects.defer(&quot;age&quot;, &quot;biography&quot;)
+
<syntaxhighlight lang="python">Person.objects.defer("age", "biography")
Person.objects.only(&quot;name&quot;)</pre>
+
Person.objects.only("name")</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Whenever you call <code>only()</code> it ''replaces'' the set of fields to load
+
每当您调用 <code>only()</code> 时,它会 ''替换'' 立即加载的字段集。 该方法的名称是助记符:'''only''' 那些字段会立即加载; 其余的被推迟。 因此,对 <code>only()</code> 的连续调用导致只考虑最终字段:
immediately. The method's name is mnemonic: '''only''' those fields are loaded
 
immediately; the remainder are deferred. Thus, successive calls to <code>only()</code>
 
result in only the final fields being considered:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,324行: 第1,830行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre># This will defer all fields except the headline.
+
<syntaxhighlight lang="python"># This will defer all fields except the headline.
Entry.objects.only(&quot;body&quot;, &quot;rating&quot;).only(&quot;headline&quot;)</pre>
+
Entry.objects.only("body", "rating").only("headline")</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Since <code>defer()</code> acts incrementally (adding fields to the deferred list), you
+
由于 <code>defer()</code> 以增量方式起作用(将字段添加到延迟列表中),您可以组合对 <code>only()</code> <code>defer()</code> 的调用,并且事情将按逻辑进行:
can combine calls to <code>only()</code> and <code>defer()</code> and things will behave
 
logically:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,338行: 第1,842行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre># Final result is that everything except &quot;headline&quot; is deferred.
+
<syntaxhighlight lang="python"># Final result is that everything except "headline" is deferred.
Entry.objects.only(&quot;headline&quot;, &quot;body&quot;).defer(&quot;body&quot;)
+
Entry.objects.only("headline", "body").defer("body")
  
 
# Final result loads headline and body immediately (only() replaces any
 
# Final result loads headline and body immediately (only() replaces any
 
# existing set of fields).
 
# existing set of fields).
Entry.objects.defer(&quot;body&quot;).only(&quot;headline&quot;, &quot;body&quot;)</pre>
+
Entry.objects.defer("body").only("headline", "body")</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
All of the cautions in the note for the [[#django.db.models.query.QuerySet.defer|<code>defer()</code>]] documentation apply to
+
[[#django.db.models.query.QuerySet.defer|defer()]] 文档注释中的所有注意事项也适用于 <code>only()</code>。 谨慎使用它,并且只有在用尽你的其他选择之后。
<code>only()</code> as well. Use it cautiously and only after exhausting your other
 
options.
 
  
Using [[#django.db.models.query.QuerySet.only|<code>only()</code>]] and omitting a field requested using [[#django.db.models.query.QuerySet.select_related|<code>select_related()</code>]]
+
使用 [[#django.db.models.query.QuerySet.only|only()]] 并省略使用 [[#django.db.models.query.QuerySet.select_related|select_related()]] 请求的字段也是一个错误。
is an error as well.
 
  
 
<div class="admonition note">
 
<div class="admonition note">
第2,359行: 第1,860行:
 
注解
 
注解
  
When calling [[../instances#django.db.models.Model|<code>save()</code>]] for instances with
+
当为具有延迟字段的实例调用 [[../instances#django.db.models.Model|save()]] 时,只会保存加载的字段。 有关更多详细信息,请参阅 [[../instances#django.db.models.Model|save()]]
deferred fields, only the loaded fields will be saved. See
 
[[../instances#django.db.models.Model|<code>save()</code>]] for more details.
 
  
  
第2,369行: 第1,868行:
 
<div id="using" class="section">
 
<div id="using" class="section">
  
==== <code>using()</code> ====
+
==== using() ====
  
; <code>using</code><span class="sig-paren">(</span>''<span class="n">alias</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">using</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">alias</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
This method is for controlling which database the <code>QuerySet</code> will be
+
如果您使用多个数据库,此方法用于控制 <code>QuerySet</code> 将针对哪个数据库进行评估。 此方法采用的唯一参数是数据库的别名,如 [[#id6|:setting:`DATABASES`]] 中所定义。
evaluated against if you are using more than one database. The only argument
 
this method takes is the alias of a database, as defined in
 
[[../../settings#std-setting-DATABASES|<code>DATABASES</code>]].
 
  
例子:
+
例如:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,385行: 第1,881行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre># queries the database with the 'default' alias.
+
<syntaxhighlight lang="python"># queries the database with the 'default' alias.
&gt;&gt;&gt; Entry.objects.all()
+
>>> Entry.objects.all()
  
 
# queries the database with the 'backup' alias
 
# queries the database with the 'backup' alias
&gt;&gt;&gt; Entry.objects.using('backup')</pre>
+
>>> Entry.objects.using('backup')</syntaxhighlight>
  
 
</div>
 
</div>
第2,398行: 第1,894行:
 
<div id="select-for-update" class="section">
 
<div id="select-for-update" class="section">
  
==== <code>select_for_update()</code> ====
+
==== select_for_update() ====
  
; <code>select_for_update</code><span class="sig-paren">(</span>''<span class="n">nowait</span><span class="o">=</span><span class="default_value">False</span>'', ''<span class="n">skip_locked</span><span class="o">=</span><span class="default_value">False</span>'', ''<span class="n">of</span><span class="o">=</span><span class="default_value">()</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">select_for_update</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">nowait</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span>'', ''<span class="n"><span class="pre">skip_locked</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span>'', ''<span class="n"><span class="pre">of</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">()</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Returns a queryset that will lock rows until the end of the transaction,
+
返回将锁定行直到事务结束的查询集,在支持的数据库上生成 <code>SELECT ... FOR UPDATE</code> SQL 语句。
generating a <code>SELECT ... FOR UPDATE</code> SQL statement on supported databases.
 
  
例子:
+
例如:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,412行: 第1,907行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.db import transaction
+
<syntaxhighlight lang="python">from django.db import transaction
  
 
entries = Entry.objects.select_for_update().filter(author=request.user)
 
entries = Entry.objects.select_for_update().filter(author=request.user)
 
with transaction.atomic():
 
with transaction.atomic():
 
     for entry in entries:
 
     for entry in entries:
         ...</pre>
+
         ...</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
When the queryset is evaluated (<code>for entry in entries</code> in this case), all
+
当查询集被评估时(在本例中为 <code>for entry in entries</code>),所有匹配的条目将被锁定,直到事务块结束,这意味着将阻止其他事务更改或获取对它们的锁。
matched entries will be locked until the end of the transaction block, meaning
 
that other transactions will be prevented from changing or acquiring locks on
 
them.
 
  
Usually, if another transaction has already acquired a lock on one of the
+
通常,如果另一个事务已经获得了对选定行之一的锁定,则查询将阻塞,直到锁定被释放。 如果这不是您想要的行为,请调用 <code>select_for_update(nowait=True)</code>。 这将使调用非阻塞。 如果另一个事务已经获取了冲突锁,则在评估查询集时将引发 [[../../exceptions#django.db|DatabaseError]]。 您也可以使用 <code>select_for_update(skip_locked=True)</code> 来忽略锁定的行。 <code>nowait</code> <code>skip_locked</code> 是互斥的,在启用这两个选项的情况下尝试调用 <code>select_for_update()</code> 将导致 <code>ValueError</code>
selected rows, the query will block until the lock is released. If this is
 
not the behavior you want, call <code>select_for_update(nowait=True)</code>. This will
 
make the call non-blocking. If a conflicting lock is already acquired by
 
another transaction, [[../../exceptions#django.db|<code>DatabaseError</code>]] will be raised when the
 
queryset is evaluated. You can also ignore locked rows by using
 
<code>select_for_update(skip_locked=True)</code> instead. The <code>nowait</code> and
 
<code>skip_locked</code> are mutually exclusive and attempts to call
 
<code>select_for_update()</code> with both options enabled will result in a
 
<code>ValueError</code>.
 
  
By default, <code>select_for_update()</code> locks all rows that are selected by the
+
默认情况下,<code>select_for_update()</code> 锁定查询选择的所有行。 例如,除了查询集模型的行之外,[[#django.db.models.query.QuerySet.select_related|select_related()]] 中指定的相关对象的行也被锁定。 如果不需要,请使用与 [[#django.db.models.query.QuerySet.select_related|select_related()]] 相同的字段语法在 <code>select_for_update(of=(...))</code> 中指定要锁定的相关对象。 使用值 <code>'self'</code> 来引用查询集的模型。
query. For example, rows of related objects specified in [[#django.db.models.query.QuerySet.select_related|<code>select_related()</code>]]
 
are locked in addition to rows of the queryset's model. If this isn't desired,
 
specify the related objects you want to lock in <code>select_for_update(of=(...))</code>
 
using the same fields syntax as [[#django.db.models.query.QuerySet.select_related|<code>select_related()</code>]]. Use the value <code>'self'</code>
 
to refer to the queryset's model.
 
  
 
<div class="admonition-lock-parents-models-in-select-for-update-of admonition">
 
<div class="admonition-lock-parents-models-in-select-for-update-of admonition">
  
Lock parents models in <code>select_for_update(of=(...))</code>
+
<code>select_for_update(of=(...))</code> 中锁定父母模型
  
If you want to lock parents models when using [[../../../topics/db/models#multi-table-inheritance|<span class="std std-ref">multi-table inheritance</span>]], you must specify parent link fields (by default
+
如果要在使用 [[../../../topics/db/models#multi-table-inheritance|多表继承]] 时锁定父模型,则必须在 <code>of</code> 参数中指定父链接字段(默认为 <code>&lt;parent_model_name&gt;_ptr</code>)。 例如:
<code>&lt;parent_model_name&gt;_ptr</code>) in the <code>of</code> argument. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,456行: 第1,933行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Restaurant.objects.select_for_update(of=('self', 'place_ptr'))</pre>
+
<syntaxhighlight lang="python">Restaurant.objects.select_for_update(of=('self', 'place_ptr'))</syntaxhighlight>
  
 
</div>
 
</div>
第2,463行: 第1,940行:
  
 
</div>
 
</div>
You can't use <code>select_for_update()</code> on nullable relations:
+
您不能在可空关系上使用 <code>select_for_update()</code>
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,469行: 第1,946行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Person.objects.select_related('hometown').select_for_update()
+
<syntaxhighlight lang="python">>>> Person.objects.select_related('hometown').select_for_update()
 
Traceback (most recent call last):
 
Traceback (most recent call last):
 
...
 
...
django.db.utils.NotSupportedError: FOR UPDATE cannot be applied to the nullable side of an outer join</pre>
+
django.db.utils.NotSupportedError: FOR UPDATE cannot be applied to the nullable side of an outer join</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
To avoid that restriction, you can exclude null objects if you don't care about
+
为了避免这种限制,如果您不关心它们,您可以排除空对象:
them:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,484行: 第1,960行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Person.objects.select_related('hometown').select_for_update().exclude(hometown=None)
+
<syntaxhighlight lang="python">>>> Person.objects.select_related('hometown').select_for_update().exclude(hometown=None)
&lt;QuerySet [&lt;Person: ...)&gt;, ...]&gt;</pre>
+
<QuerySet [<Person: ...)>, ...]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Currently, the <code>postgresql</code>, <code>oracle</code>, and <code>mysql</code> database
+
目前,<code>postgresql</code><code>oracle</code> <code>mysql</code> 数据库后端支持 <code>select_for_update()</code>。 但是,MySQL 不支持 [X35X] 参数,并且仅在 MySQL 8.0.1+ 上支持 <code>nowait</code> <code>skip_locked</code> 参数。
backends support <code>select_for_update()</code>. However, MySQL doesn't support the
 
<code>of</code> argument and the <code>nowait</code> and <code>skip_locked</code> arguments are supported
 
only on MySQL 8.0.1+.
 
  
Passing <code>nowait=True</code>, <code>skip_locked=True</code>, or <code>of</code> to
+
使用不支持这些选项的数据库后端(例如 MySQL)将 <code>nowait=True</code><code>skip_locked=True</code> <code>of</code> 传递给 <code>select_for_update()</code>,会引发 NotSupportedError[ X160X]。 这可以防止代码意外阻塞。
<code>select_for_update()</code> using database backends that do not support these
 
options, such as MySQL, raises a [[../../exceptions#django.db|<code>NotSupportedError</code>]]. This
 
prevents code from unexpectedly blocking.
 
  
Evaluating a queryset with <code>select_for_update()</code> in autocommit mode on
+
在支持 <code>SELECT ... FOR UPDATE</code> 的后端在自动提交模式下使用 <code>select_for_update()</code> 评估查询集是一个 [[../../exceptions#django.db.transaction|TransactionManagementError]] 错误,因为在这种情况下行未锁定。 如果允许,这将促进数据损坏,并且很容易由调用预期在事务之外的事务中运行的代码引起。
backends which support <code>SELECT ... FOR UPDATE</code> is a
 
[[../../exceptions#django.db.transaction|<code>TransactionManagementError</code>]] error because the
 
rows are not locked in that case. If allowed, this would facilitate data
 
corruption and could easily be caused by calling code that expects to be run in
 
a transaction outside of one.
 
  
Using <code>select_for_update()</code> on backends which do not support
+
在不支持 <code>SELECT ... FOR UPDATE</code> 的后端(例如 SQLite)上使用 <code>select_for_update()</code> 将不起作用。 <code>SELECT ... FOR UPDATE</code> 不会添加到查询中,如果在自动提交模式下使用 <code>select_for_update()</code>,则不会引发错误。
<code>SELECT ... FOR UPDATE</code> (such as SQLite) will have no effect.
 
<code>SELECT ... FOR UPDATE</code> will not be added to the query, and an error isn't
 
raised if <code>select_for_update()</code> is used in autocommit mode.
 
  
 
<div class="admonition warning">
 
<div class="admonition warning">
第2,516行: 第1,978行:
 
警告
 
警告
  
Although <code>select_for_update()</code> normally fails in autocommit mode, since
+
尽管 <code>select_for_update()</code> 在自动提交模式下通常会失败,但由于 [[../../../topics/testing/tools#django.test|TestCase]] 自动将每个测试包装在一个事务中,即使在 [[../../../topics/db/transactions#django.db.transaction|之外调用 <code>TestCase</code> 中的 <code>select_for_update()</code> atomic()]] 块将(可能出乎意料地)通过而不引发 <code>TransactionManagementError</code>。 要正确测试 <code>select_for_update()</code>,您应该使用 [[../../../topics/testing/tools#django.test|TransactionTestCase]]
[[../../../topics/testing/tools#django.test|<code>TestCase</code>]] automatically wraps each test in a
 
transaction, calling <code>select_for_update()</code> in a <code>TestCase</code> even outside
 
an [[../../../topics/db/transactions#django.db.transaction|<code>atomic()</code>]] block will (perhaps unexpectedly)
 
pass without raising a <code>TransactionManagementError</code>. To properly test
 
<code>select_for_update()</code> you should use
 
[[../../../topics/testing/tools#django.test|<code>TransactionTestCase</code>]].
 
  
  
第2,528行: 第1,984行:
 
<div class="admonition-certain-expressions-may-not-be-supported admonition">
 
<div class="admonition-certain-expressions-may-not-be-supported admonition">
  
Certain expressions may not be supported
+
可能不支持某些表达方式
  
PostgreSQL doesn't support <code>select_for_update()</code> with
+
PostgreSQL 不支持 <code>select_for_update()</code> [[../expressions#django.db.models.expressions|Window]] 表达式。
[[../expressions#django.db.models.expressions|<code>Window</code>]] expressions.
 
  
  
第2,539行: 第1,994行:
 
<div id="raw" class="section">
 
<div id="raw" class="section">
  
==== <code>raw()</code> ====
+
==== raw() ====
  
; <code>raw</code><span class="sig-paren">(</span>''<span class="n">raw_query</span>'', ''<span class="n">params</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">translations</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">raw</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">raw_query</span></span>'', ''<span class="n"><span class="pre">params</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">translations</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Takes a raw SQL query, executes it, and returns a
+
获取原始 SQL 查询,执行它,并返回一个 <code>django.db.models.query.RawQuerySet</code> 实例。 这个 <code>RawQuerySet</code> 实例可以像普通的 <code>QuerySet</code> 一样迭代以提供对象实例。
<code>django.db.models.query.RawQuerySet</code> instance. This <code>RawQuerySet</code> instance
 
can be iterated over just like an normal <code>QuerySet</code> to provide object instances.
 
  
See the [[../../../topics/db/sql|<span class="doc">执行原生 SQL 查询</span>]] for more information.
+
有关详细信息,请参阅 [[../../../topics/db/sql|执行原始 SQL 查询]]
  
 
<div class="admonition warning">
 
<div class="admonition warning">
第2,554行: 第2,007行:
 
警告
 
警告
  
<code>raw()</code> always triggers a new query and doesn't account for previous
+
<code>raw()</code> 总是触发一个新的查询并且不考虑之前的过滤。 因此,通常应该从 <code>Manager</code> 或新的 <code>QuerySet</code> 实例调用它。
filtering. As such, it should generally be called from the <code>Manager</code> or
 
from a fresh <code>QuerySet</code> instance.
 
  
  
第2,566行: 第2,017行:
 
<div id="operators-that-return-new-querysets" class="section">
 
<div id="operators-that-return-new-querysets" class="section">
  
=== Operators that return new <code>QuerySet</code>s ===
+
=== 返回新 QuerySet 的运算符 ===
  
Combined querysets must use the same model.
+
组合的查询集必须使用相同的模型。
  
 
<div id="and" class="section">
 
<div id="and" class="section">
  
==== AND (<code>&amp;</code>) ====
+
==== (&amp;) ====
  
Combines two <code>QuerySet</code>s using the SQL <code>AND</code> operator.
+
使用 SQL <code>AND</code> 运算符组合两个 <code>QuerySet</code>
  
The following are equivalent:
+
以下是等效的:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,582行: 第2,033行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Model.objects.filter(x=1) &amp; Model.objects.filter(y=2)
+
<syntaxhighlight lang="python">Model.objects.filter(x=1) & Model.objects.filter(y=2)
 
Model.objects.filter(x=1, y=2)
 
Model.objects.filter(x=1, y=2)
 
from django.db.models import Q
 
from django.db.models import Q
Model.objects.filter(Q(x=1) &amp; Q(y=2))</pre>
+
Model.objects.filter(Q(x=1) & Q(y=2))</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalent:
+
SQL 等价于:
  
 
<div class="highlight-sql notranslate">
 
<div class="highlight-sql notranslate">
第2,596行: 第2,047行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE x=1 AND y=2</pre>
+
<syntaxhighlight lang="sql">SELECT ... WHERE x=1 AND y=2</syntaxhighlight>
  
 
</div>
 
</div>
第2,605行: 第2,056行:
 
<div id="or" class="section">
 
<div id="or" class="section">
  
==== OR (<code>|</code>) ====
+
==== (|) ====
  
Combines two <code>QuerySet</code>s using the SQL <code>OR</code> operator.
+
使用 SQL <code>OR</code> 运算符组合两个 <code>QuerySet</code>
  
The following are equivalent:
+
以下是等效的:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,615行: 第2,066行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Model.objects.filter(x=1) | Model.objects.filter(y=2)
+
<syntaxhighlight lang="python">Model.objects.filter(x=1) | Model.objects.filter(y=2)
 
from django.db.models import Q
 
from django.db.models import Q
Model.objects.filter(Q(x=1) | Q(y=2))</pre>
+
Model.objects.filter(Q(x=1) | Q(y=2))</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalent:
+
SQL 等价于:
  
 
<div class="highlight-sql notranslate">
 
<div class="highlight-sql notranslate">
第2,628行: 第2,079行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE x=1 OR y=2</pre>
+
<syntaxhighlight lang="sql">SELECT ... WHERE x=1 OR y=2</syntaxhighlight>
  
 
</div>
 
</div>
第2,639行: 第2,090行:
 
<div id="methods-that-do-not-return-querysets" class="section">
 
<div id="methods-that-do-not-return-querysets" class="section">
  
=== Methods that do not return <code>QuerySet</code>s ===
+
=== 不返回 QuerySets 的方法 ===
  
The following <code>QuerySet</code> methods evaluate the <code>QuerySet</code> and return
+
以下 <code>QuerySet</code> 方法评估 <code>QuerySet</code> 并返回 ''以外的'' <code>QuerySet</code>
something ''other than'' a <code>QuerySet</code>.
 
  
These methods do not use a cache (see [[../../../topics/db/queries#caching-and-querysets|<span class="std std-ref">缓存和 QuerySet</span>]]). Rather,
+
这些方法不使用缓存(参见 [[../../../topics/db/queries#caching-and-querysets|Caching 和 QuerySets]])。 相反,他们每次被调用时都会查询数据库。
they query the database each time they're called.
 
  
 
<div id="get" class="section">
 
<div id="get" class="section">
  
==== <code>get()</code> ====
+
==== get() ====
  
; <code>get</code><span class="sig-paren">(</span>''<span class="o">**</span><span class="n">kwargs</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">get</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Returns the object matching the given lookup parameters, which should be in
+
返回与给定查找参数匹配的对象,该对象应采用 [[#id10|字段查找]] 中描述的格式。
the format described in [[#id4|Field lookups]].
 
  
<code>get()</code> raises [[../../exceptions#django.core.exceptions|<code>MultipleObjectsReturned</code>]] if more
+
<code>get()</code> 如果找到多个对象,则引发 [[../../exceptions#django.core.exceptions|MultipleObjectsReturned]][[../../exceptions#django.core.exceptions|MultipleObjectsReturned]] 异常是模型类的一个属性。
than one object was found. The
 
[[../../exceptions#django.core.exceptions|<code>MultipleObjectsReturned</code>]] exception is an
 
attribute of the model class.
 
  
<code>get()</code> raises a [[../instances#django.db.models.Model|<code>DoesNotExist</code>]] exception if an
+
<code>get()</code> 如果未找到给定参数的对象,则会引发 [[../instances#django.db.models.Model|DoesNotExist]] 异常。 这个异常是模型类的一个属性。 例子:
object wasn't found for the given parameters. This exception is an attribute
 
of the model class. Example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,670行: 第2,113行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.get(id='foo') # raises Entry.DoesNotExist</pre>
+
<syntaxhighlight lang="python">Entry.objects.get(id='foo') # raises Entry.DoesNotExist</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The [[../instances#django.db.models.Model|<code>DoesNotExist</code>]] exception inherits from
+
[[../instances#django.db.models.Model|DoesNotExist]] 异常继承自 [[../../exceptions#django.core.exceptions|django.core.exceptions.ObjectDoesNotExist]],因此您可以针对多个 [[../instances#django.db.models.Model|DoesNotExist]] 异常。 例子:
[[../../exceptions#django.core.exceptions|<code>django.core.exceptions.ObjectDoesNotExist</code>]], so you can target multiple
 
[[../instances#django.db.models.Model|<code>DoesNotExist</code>]] exceptions. Example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,683行: 第2,124行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.core.exceptions import ObjectDoesNotExist
+
<syntaxhighlight lang="python">from django.core.exceptions import ObjectDoesNotExist
 
try:
 
try:
 
     e = Entry.objects.get(id=3)
 
     e = Entry.objects.get(id=3)
 
     b = Blog.objects.get(id=1)
 
     b = Blog.objects.get(id=1)
 
except ObjectDoesNotExist:
 
except ObjectDoesNotExist:
     print(&quot;Either the entry or blog doesn't exist.&quot;)</pre>
+
     print("Either the entry or blog doesn't exist.")</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
If you expect a queryset to return one row, you can use <code>get()</code> without any
+
如果您希望查询集返回一行,则可以使用不带任何参数的 <code>get()</code> 来返回该行的对象:
arguments to return the object for that row:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,700行: 第2,140行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>entry = Entry.objects.filter(...).exclude(...).get()</pre>
+
<syntaxhighlight lang="python">entry = Entry.objects.filter(...).exclude(...).get()</syntaxhighlight>
  
 
</div>
 
</div>
第2,709行: 第2,149行:
 
<div id="create" class="section">
 
<div id="create" class="section">
  
==== <code>create()</code> ====
+
==== create() ====
  
; <code>create</code><span class="sig-paren">(</span>''<span class="o">**</span><span class="n">kwargs</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">create</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
A convenience method for creating an object and saving it all in one step. Thus:
+
一种创建对象并将其全部保存在一个步骤中的便捷方法。 因此:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,720行: 第2,160行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>p = Person.objects.create(first_name=&quot;Bruce&quot;, last_name=&quot;Springsteen&quot;)</pre>
+
<syntaxhighlight lang="python">p = Person.objects.create(first_name="Bruce", last_name="Springsteen")</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
和:
+
和:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,731行: 第2,171行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>p = Person(first_name=&quot;Bruce&quot;, last_name=&quot;Springsteen&quot;)
+
<syntaxhighlight lang="python">p = Person(first_name="Bruce", last_name="Springsteen")
p.save(force_insert=True)</pre>
+
p.save(force_insert=True)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
are equivalent.
+
是等效的。
  
The [[../instances#ref-models-force-insert|<span class="std std-ref">force_insert</span>]] parameter is documented
+
[[../instances#ref-models-force-insert|force_insert]] 参数在别处有说明,但这意味着总是会创建一个新对象。 通常你不需要担心这个。 但是,如果您的模型包含您设置的手动主键值,并且该值已存在于数据库中,则调用 <code>create()</code> 将失败并显示 [[../../exceptions#django.db|IntegrityError]],因为主键必须是唯一的. 如果您使用手动主键,请准备好处理异常。
elsewhere, but all it means is that a new object will always be created.
 
Normally you won't need to worry about this. However, if your model contains a
 
manual primary key value that you set and if that value already exists in the
 
database, a call to <code>create()</code> will fail with an
 
[[../../exceptions#django.db|<code>IntegrityError</code>]] since primary keys must be unique. Be
 
prepared to handle the exception if you are using manual primary keys.
 
  
  
第2,751行: 第2,185行:
 
<div id="get-or-create" class="section">
 
<div id="get-or-create" class="section">
  
==== <code>get_or_create()</code> ====
+
==== get_or_create() ====
  
; <code>get_or_create</code><span class="sig-paren">(</span>''<span class="n">defaults</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="o">**</span><span class="n">kwargs</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">get_or_create</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">defaults</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
A convenience method for looking up an object with the given <code>kwargs</code> (may be
+
一种使用给定 <code>kwargs</code> 查找对象的便捷方法(如果您的模型具有所有字段的默认值,则可能为空),如有必要,创建一个。
empty if your model has defaults for all fields), creating one if necessary.
 
  
Returns a tuple of <code>(object, created)</code>, where <code>object</code> is the retrieved or
+
返回 <code>(object, created)</code> 的元组,其中 <code>object</code> 是检索或创建的对象,<code>created</code> 是指定是否创建新对象的布尔值。
created object and <code>created</code> is a boolean specifying whether a new object was
 
created.
 
  
This is meant to prevent duplicate objects from being created when requests are
+
这是为了防止在并行发出请求时创建重复的对象,并作为样板代码的快捷方式。 例如:
made in parallel, and as a shortcut to boilerplatish code. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,770行: 第2,200行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>try:
+
<syntaxhighlight lang="python">try:
 
     obj = Person.objects.get(first_name='John', last_name='Lennon')
 
     obj = Person.objects.get(first_name='John', last_name='Lennon')
 
except Person.DoesNotExist:
 
except Person.DoesNotExist:
 
     obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
 
     obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
     obj.save()</pre>
+
     obj.save()</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Here, with concurrent requests, multiple attempts to save a <code>Person</code> with
+
这里,对于并发请求,可能会多次尝试保存具有相同参数的 <code>Person</code>。 为了避免这种竞争条件,上面的例子可以使用 <code>get_or_create()</code> 重写,如下所示:
the same parameters may be made. To avoid this race condition, the above
 
example can be rewritten using <code>get_or_create()</code> like so:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,787行: 第2,215行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>obj, created = Person.objects.get_or_create(
+
<syntaxhighlight lang="python">obj, created = Person.objects.get_or_create(
 
     first_name='John',
 
     first_name='John',
 
     last_name='Lennon',
 
     last_name='Lennon',
 
     defaults={'birthday': date(1940, 10, 9)},
 
     defaults={'birthday': date(1940, 10, 9)},
)</pre>
+
)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Any keyword arguments passed to <code>get_or_create()</code> — ''except'' an optional one
+
任何传递给 <code>get_or_create()</code> 的关键字参数 — ''除外'' 一个称为 <code>defaults</code> 的可选参数 将在 [[#django.db.models.query.QuerySet.get|get()]] 调用中使用。 如果找到对象,<code>get_or_create()</code> 返回该对象的元组和 <code>False</code>
called <code>defaults</code> — will be used in a [[#django.db.models.query.QuerySet.get|<code>get()</code>]] call. If an object is
 
found, <code>get_or_create()</code> returns a tuple of that object and <code>False</code>.
 
  
 
<div class="admonition warning">
 
<div class="admonition warning">
第2,804行: 第2,230行:
 
警告
 
警告
  
This method is atomic assuming that the database enforces uniqueness of the
+
此方法是原子的,假设数据库强制关键字参数的唯一性(请参阅 [[../fields#django.db.models.Field|unique]] [[../options#django.db.models.Options|unique_together]])。 如果关键字参数中使用的字段没有唯一性约束,则对此方法的并发调用可能会导致插入具有相同参数的多行。
keyword arguments (see [[../fields#django.db.models.Field|<code>unique</code>]] or
 
[[../options#django.db.models.Options|<code>unique_together</code>]]). If the fields used in the
 
keyword arguments do not have a uniqueness constraint, concurrent calls to
 
this method may result in multiple rows with the same parameters being
 
inserted.
 
  
  
 
</div>
 
</div>
You can specify more complex conditions for the retrieved object by chaining
+
您可以通过将 <code>get_or_create()</code> <code>filter()</code> 链接起来并使用 [[#django.db.models.Q|Q 对象]] 来为检索到的对象指定更复杂的条件。 例如,检索 Robert Bob Marley(如果存在),否则创建后者:
<code>get_or_create()</code> with <code>filter()</code> and using [[#django.db.models.Q|<code>Q objects</code>]]. For example, to retrieve Robert or Bob Marley if either
 
exists, and create the latter otherwise:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,821行: 第2,240行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.db.models import Q
+
<syntaxhighlight lang="python">from django.db.models import Q
  
 
obj, created = Person.objects.filter(
 
obj, created = Person.objects.filter(
 
     Q(first_name='Bob') | Q(first_name='Robert'),
 
     Q(first_name='Bob') | Q(first_name='Robert'),
).get_or_create(last_name='Marley', defaults={'first_name': 'Bob'})</pre>
+
).get_or_create(last_name='Marley', defaults={'first_name': 'Bob'})</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
If multiple objects are found, <code>get_or_create()</code> raises
+
如果找到多个对象,<code>get_or_create()</code> 会引发 [[../../exceptions#django.core.exceptions|MultipleObjectsReturned]]。 如果''没有''找到一个对象,<code>get_or_create()</code>将实例化并保存一个新对象,返回一个新对象和<code>True</code>的元组。 新对象将根据以下算法大致创建:
[[../../exceptions#django.core.exceptions|<code>MultipleObjectsReturned</code>]]. If an object is ''not''
 
found, <code>get_or_create()</code> will instantiate and save a new object, returning a
 
tuple of the new object and <code>True</code>. The new object will be created roughly
 
according to this algorithm:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,840行: 第2,255行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>params = {k: v for k, v in kwargs.items() if '__' not in k}
+
<syntaxhighlight lang="python">params = {k: v for k, v in kwargs.items() if '__' not in k}
 
params.update({k: v() if callable(v) else v for k, v in defaults.items()})
 
params.update({k: v() if callable(v) else v for k, v in defaults.items()})
 
obj = self.model(**params)
 
obj = self.model(**params)
obj.save()</pre>
+
obj.save()</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
In English, that means start with any non-<code>'defaults'</code> keyword argument that
+
在英语中,这意味着以任何不包含双下划线的非 <code>'defaults'</code> 关键字参数开头(这表示不精确的查找)。 然后添加 <code>defaults</code> 的内容,必要时覆盖任何键,并将结果用作模型类的关键字参数。 如果 <code>defaults</code> 中有任何可调用对象,请评估它们。 如上所述,这是所用算法的简化,但它包含所有相关细节。 内部实现具有比这更多的错误检查并处理一些额外的边缘条件; 如果您有兴趣,请阅读代码。
doesn't contain a double underscore (which would indicate a non-exact lookup).
 
Then add the contents of <code>defaults</code>, overriding any keys if necessary, and
 
use the result as the keyword arguments to the model class. If there are any
 
callables in <code>defaults</code>, evaluate them. As hinted at above, this is a
 
simplification of the algorithm that is used, but it contains all the pertinent
 
details. The internal implementation has some more error-checking than this and
 
handles some extra edge-conditions; if you're interested, read the code.
 
  
If you have a field named <code>defaults</code> and want to use it as an exact lookup in
+
如果您有一个名为 <code>defaults</code> 的字段并希望将其用作 <code>get_or_create()</code> 中的精确查找,只需使用 <code>'defaults__exact'</code>,如下所示:
<code>get_or_create()</code>, just use <code>'defaults__exact'</code>, like so:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,864行: 第2,271行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Foo.objects.get_or_create(defaults__exact='bar', defaults={'defaults': 'baz'})</pre>
+
<syntaxhighlight lang="python">Foo.objects.get_or_create(defaults__exact='bar', defaults={'defaults': 'baz'})</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The <code>get_or_create()</code> method has similar error behavior to [[#django.db.models.query.QuerySet.create|<code>create()</code>]]
+
当您使用手动指定的主键时,<code>get_or_create()</code> 方法具有与 [[#django.db.models.query.QuerySet.create|create()]] 类似的错误行为。 如果需要创建对象并且密钥已经存在于数据库中,则会引发 [[../../exceptions#django.db|IntegrityError]]
when you're using manually specified primary keys. If an object needs to be
 
created and the key already exists in the database, an
 
[[../../exceptions#django.db|<code>IntegrityError</code>]] will be raised.
 
  
Finally, a word on using <code>get_or_create()</code> in Django views. Please make sure
+
最后,谈谈在 Django 视图中使用 <code>get_or_create()</code>。 请确保仅在 <code>POST</code> 请求中使用它,除非您有充分的理由不这样做。 <code>GET</code> 请求不应对数据产生任何影响。 相反,只要对页面的请求对您的数据有副作用,就使用 <code>POST</code>。 有关更多信息,请参阅 HTTP 规范中的 <span id="index-0" class="target"></span>[https://tools.ietf.org/html/rfc7231.html#section-4.2.1 安全方法]
to use it only in <code>POST</code> requests unless you have a good reason not to.
 
<code>GET</code> requests shouldn't have any effect on data. Instead, use <code>POST</code>
 
whenever a request to a page has a side effect on your data. For more, see
 
<span id="index-0" class="target"></span>[https://tools.ietf.org/html/rfc7231.html#section-4.2.1 '''Safe methods'''] in the HTTP spec.
 
  
 
<div class="admonition warning">
 
<div class="admonition warning">
第2,884行: 第2,284行:
 
警告
 
警告
  
You can use <code>get_or_create()</code> through [[../fields#django.db.models|<code>ManyToManyField</code>]]
+
您可以使用 <code>get_or_create()</code> [[../fields#django.db.models|ManyToManyField]] 属性和反向关系。 在这种情况下,您将限制该关系上下文内的查询。 如果您不始终如一地使用它,这可能会导致您出现一些完整性问题。
attributes and reverse relations. In that case you will restrict the queries
 
inside the context of that relation. That could lead you to some integrity
 
problems if you don't use it consistently.
 
  
Being the following models:
+
有以下型号:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,895行: 第2,292行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>class Chapter(models.Model):
+
<syntaxhighlight lang="python">class Chapter(models.Model):
 
     title = models.CharField(max_length=255, unique=True)
 
     title = models.CharField(max_length=255, unique=True)
  
 
class Book(models.Model):
 
class Book(models.Model):
 
     title = models.CharField(max_length=256)
 
     title = models.CharField(max_length=256)
     chapters = models.ManyToManyField(Chapter)</pre>
+
     chapters = models.ManyToManyField(Chapter)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
You can use <code>get_or_create()</code> through Book's chapters field, but it only
+
您可以通过 Book 的章节字段使用 <code>get_or_create()</code>,但它只能在该书的上下文中获取:
fetches inside the context of that book:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,912行: 第2,308行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; book = Book.objects.create(title=&quot;Ulysses&quot;)
+
<syntaxhighlight lang="python">>>> book = Book.objects.create(title="Ulysses")
&gt;&gt;&gt; book.chapters.get_or_create(title=&quot;Telemachus&quot;)
+
>>> book.chapters.get_or_create(title="Telemachus")
(&lt;Chapter: Telemachus&gt;, True)
+
(<Chapter: Telemachus>, True)
&gt;&gt;&gt; book.chapters.get_or_create(title=&quot;Telemachus&quot;)
+
>>> book.chapters.get_or_create(title="Telemachus")
(&lt;Chapter: Telemachus&gt;, False)
+
(<Chapter: Telemachus>, False)
&gt;&gt;&gt; Chapter.objects.create(title=&quot;Chapter 1&quot;)
+
>>> Chapter.objects.create(title="Chapter 1")
&lt;Chapter: Chapter 1&gt;
+
<Chapter: Chapter 1>
&gt;&gt;&gt; book.chapters.get_or_create(title=&quot;Chapter 1&quot;)
+
>>> book.chapters.get_or_create(title="Chapter 1")
# Raises IntegrityError</pre>
+
# Raises IntegrityError</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
This is happening because it's trying to get or create &quot;Chapter 1&quot; through the
+
之所以发生这种情况,是因为它试图通过“尤利西斯”一书获取或创建“第 1 章”,但它无法执行任何操作:该关系无法获取该章节,因为它与该书无关,但是它也不能创建它,因为 <code>title</code> 字段应该是唯一的。
book &quot;Ulysses&quot;, but it can't do any of them: the relation can't fetch that
 
chapter because it isn't related to that book, but it can't create it either
 
because <code>title</code> field should be unique.
 
  
  
第2,936行: 第2,329行:
 
<div id="update-or-create" class="section">
 
<div id="update-or-create" class="section">
  
==== <code>update_or_create()</code> ====
+
==== update_or_create() ====
  
; <code>update_or_create</code><span class="sig-paren">(</span>''<span class="n">defaults</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="o">**</span><span class="n">kwargs</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">update_or_create</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">defaults</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
A convenience method for updating an object with the given <code>kwargs</code>, creating
+
一种使用给定 <code>kwargs</code> 更新对象的便捷方法,必要时创建一个新对象。 <code>defaults</code> 是用于更新对象的(字段,值)对的字典。 <code>defaults</code> 中的值可以是可调用的。
a new one if necessary. The <code>defaults</code> is a dictionary of (field, value)
 
pairs used to update the object. The values in <code>defaults</code> can be callables.
 
  
Returns a tuple of <code>(object, created)</code>, where <code>object</code> is the created or
+
返回 <code>(object, created)</code> 元组,其中 <code>object</code> 是创建或更新的对象,<code>created</code> 是一个布尔值,指定是否创建了新对象。
updated object and <code>created</code> is a boolean specifying whether a new object was
 
created.
 
  
The <code>update_or_create</code> method tries to fetch an object from database based on
+
<code>update_or_create</code> 方法尝试根据给定的 <code>kwargs</code> 从数据库中获取一个对象。 如果找到匹配项,它会更新 <code>defaults</code> 字典中传递的字段。
the given <code>kwargs</code>. If a match is found, it updates the fields passed in the
 
<code>defaults</code> dictionary.
 
  
This is meant as a shortcut to boilerplatish code. For example:
+
这意味着作为样板代码的快捷方式。 例如:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,959行: 第2,346行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>defaults = {'first_name': 'Bob'}
+
<syntaxhighlight lang="python">defaults = {'first_name': 'Bob'}
 
try:
 
try:
 
     obj = Person.objects.get(first_name='John', last_name='Lennon')
 
     obj = Person.objects.get(first_name='John', last_name='Lennon')
第2,969行: 第2,356行:
 
     new_values.update(defaults)
 
     new_values.update(defaults)
 
     obj = Person(**new_values)
 
     obj = Person(**new_values)
     obj.save()</pre>
+
     obj.save()</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
This pattern gets quite unwieldy as the number of fields in a model goes up.
+
随着模型中字段数量的增加,这种模式变得非常笨拙。 上面的例子可以使用 <code>update_or_create()</code> 重写,如下所示:
The above example can be rewritten using <code>update_or_create()</code> like so:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第2,981行: 第2,367行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>obj, created = Person.objects.update_or_create(
+
<syntaxhighlight lang="python">obj, created = Person.objects.update_or_create(
 
     first_name='John', last_name='Lennon',
 
     first_name='John', last_name='Lennon',
 
     defaults={'first_name': 'Bob'},
 
     defaults={'first_name': 'Bob'},
)</pre>
+
)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
For detailed description how names passed in <code>kwargs</code> are resolved see
+
有关如何解析 <code>kwargs</code> 中传递的名称的详细说明,请参阅 [[#django.db.models.query.QuerySet.get_or_create|get_or_create()]]
[[#django.db.models.query.QuerySet.get_or_create|<code>get_or_create()</code>]].
 
  
As described above in [[#django.db.models.query.QuerySet.get_or_create|<code>get_or_create()</code>]], this method is prone to a
+
如上文 [[#django.db.models.query.QuerySet.get_or_create|get_or_create()]] 中所述,此方法容易出现竞争条件,如果未在数据库级别强制执行唯一性,则可能导致同时插入多行。
race-condition which can result in multiple rows being inserted simultaneously
 
if uniqueness is not enforced at the database level.
 
  
Like [[#django.db.models.query.QuerySet.get_or_create|<code>get_or_create()</code>]] and [[#django.db.models.query.QuerySet.create|<code>create()</code>]], if you're using manually
+
[[#django.db.models.query.QuerySet.get_or_create|get_or_create()]] [[#django.db.models.query.QuerySet.create|create()]],如果您使用手动指定的主键并且需要创建一个对象但该键已经存在于数据库中,则 [[../../exceptions#django.db|引发 IntegrityError]]
specified primary keys and an object needs to be created but the key already
 
exists in the database, an [[../../exceptions#django.db|<code>IntegrityError</code>]] is raised.
 
  
  
第3,004行: 第2,385行:
 
<div id="bulk-create" class="section">
 
<div id="bulk-create" class="section">
  
==== <code>bulk_create()</code> ====
+
==== bulk_create() ====
  
; <code>bulk_create</code><span class="sig-paren">(</span>''<span class="n">objs</span>'', ''<span class="n">batch_size</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">ignore_conflicts</span><span class="o">=</span><span class="default_value">False</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">bulk_create</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">objs</span></span>'', ''<span class="n"><span class="pre">batch_size</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">ignore_conflicts</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
This method inserts the provided list of objects into the database in an
+
此方法以高效的方式将提供的对象列表插入到数据库中(通常只有 1 个查询,无论有多少个对象):
efficient manner (generally only 1 query, no matter how many objects there
 
are):
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,017行: 第2,396行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Entry.objects.bulk_create([
+
<syntaxhighlight lang="python">>>> Entry.objects.bulk_create([
 
...    Entry(headline='This is a test'),
 
...    Entry(headline='This is a test'),
 
...    Entry(headline='This is only a test'),
 
...    Entry(headline='This is only a test'),
... ])</pre>
+
... ])</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
This has a number of caveats though:
+
不过这有一些注意事项:
  
 
<ul>
 
<ul>
<li><p>The model's <code>save()</code> method will not be called, and the <code>pre_save</code> and
+
<li><p>不会调用模型的<code>save()</code>方法,也不会发送<code>pre_save</code><code>post_save</code>信号。</p></li>
<code>post_save</code> signals will not be sent.</p></li>
+
<li><p>在多表继承的情况下,它不能与子模型一起工作。</p></li>
<li><p>It does not work with child models in a multi-table inheritance scenario.</p></li>
+
<li><p>如果模型的主键是 [[../fields#django.db.models|AutoField]],它不会像 <code>save()</code> 那样检索和设置主键属性,除非数据库后端支持它(当前是 PostgreSQL)。</p></li>
<li><p>If the model's primary key is an [[../fields#django.db.models|<code>AutoField</code>]] it
+
<li><p>对于多对多的关系,它是行不通的。</p></li>
does not retrieve and set the primary key attribute, as <code>save()</code> does,
+
<li><p>它将 <code>objs</code> 转换为一个列表,如果它是一个生成器,它会完全评估 <code>objs</code>。 强制转换允许检查所有对象,以便可以首先插入具有手动设置的主键的任何对象。 如果您想批量插入对象而不一次评估整个生成器,只要对象没有任何手动设置的主键,您就可以使用此技术:</p>
unless the database backend supports it (currently PostgreSQL).</p></li>
 
<li><p>It does not work with many-to-many relationships.</p></li>
 
<li><p>It casts <code>objs</code> to a list, which fully evaluates <code>objs</code> if it's a
 
generator. The cast allows inspecting all objects so that any objects with a
 
manually set primary key can be inserted first. If you want to insert objects
 
in batches without evaluating the entire generator at once, you can use this
 
technique as long as the objects don't have any manually set primary keys:</p>
 
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from itertools import islice
+
<syntaxhighlight lang="python">from itertools import islice
  
 
batch_size = 100
 
batch_size = 100
第3,052行: 第2,424行:
 
     if not batch:
 
     if not batch:
 
         break
 
         break
     Entry.objects.bulk_create(batch, batch_size)</pre>
+
     Entry.objects.bulk_create(batch, batch_size)</syntaxhighlight>
  
 
</div>
 
</div>
第3,058行: 第2,430行:
 
</div></li></ul>
 
</div></li></ul>
  
The <code>batch_size</code> parameter controls how many objects are created in a single
+
<code>batch_size</code> 参数控制在单个查询中创建的对象数量。 默认是批量创建所有对象,SQLite 除外,默认情况下每个查询最多使用 999 个变量。
query. The default is to create all objects in one batch, except for SQLite
 
where the default is such that at most 999 variables per query are used.
 
  
On databases that support it (all except PostgreSQL &lt; 9.5 and Oracle), setting
+
在支持它的数据库上(除了 PostgreSQL &lt; 9.5 和 Oracle),设置<code>ignore_conflicts</code>参数为<code>True</code>告诉数据库忽略插入失败约束(例如重复唯一值)的任何行的失败。 启用此参数将禁用在每个模型实例上设置主键(如果数据库通常支持它)。
the <code>ignore_conflicts</code> parameter to <code>True</code> tells the database to ignore
 
failure to insert any rows that fail constraints such as duplicate unique
 
values. Enabling this parameter disables setting the primary key on each model
 
instance (if the database normally supports it).
 
  
 
<div class="versionchanged">
 
<div class="versionchanged">
  
The <code>ignore_conflicts</code> parameter was added.
+
<span class="versionmodified changed"> 2.2 版更改: </span> 添加了 <code>ignore_conflicts</code> 参数。
  
  
第3,078行: 第2,444行:
 
<div id="bulk-update" class="section">
 
<div id="bulk-update" class="section">
  
==== <code>bulk_update()</code> ====
+
==== bulk_update() ====
  
 
<div class="versionadded">
 
<div class="versionadded">
  
 +
<span class="versionmodified added">2.2 版中的新功能。</span>
  
  
 
</div>
 
</div>
; <code>bulk_update</code><span class="sig-paren">(</span>''<span class="n">objs</span>'', ''<span class="n">fields</span>'', ''<span class="n">batch_size</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">bulk_update</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">objs</span></span>'', ''<span class="n"><span class="pre">fields</span></span>'', ''<span class="n"><span class="pre">batch_size</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
This method efficiently updates the given fields on the provided model
+
此方法有效地更新提供的模型实例上的给定字段,通常使用一个查询:
instances, generally with one query:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,095行: 第2,461行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; objs = [
+
<syntaxhighlight lang="python">>>> objs = [
 
...    Entry.objects.create(headline='Entry 1'),
 
...    Entry.objects.create(headline='Entry 1'),
 
...    Entry.objects.create(headline='Entry 2'),
 
...    Entry.objects.create(headline='Entry 2'),
 
... ]
 
... ]
&gt;&gt;&gt; objs[0].headline = 'This is entry 1'
+
>>> objs[0].headline = 'This is entry 1'
&gt;&gt;&gt; objs[1].headline = 'This is entry 2'
+
>>> objs[1].headline = 'This is entry 2'
&gt;&gt;&gt; Entry.objects.bulk_update(objs, ['headline'])</pre>
+
>>> Entry.objects.bulk_update(objs, ['headline'])</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
[[#django.db.models.query.QuerySet.update|<code>QuerySet.update()</code>]] is used to save the changes, so this is more efficient
+
[[#django.db.models.query.QuerySet.update|QuerySet.update()]] 用于保存更改,因此这比遍历模型列表并在每个模型上调用 <code>save()</code> 更有效,但它有一些警告:
than iterating through the list of models and calling <code>save()</code> on each of
 
them, but it has a few caveats:
 
  
* You cannot update the model's primary key.
+
* 您无法更新模型的主键。
* Each model's <code>save()</code> method isn't called, and the [[../../signals#django.db.models.signals|<code>pre_save</code>]] and [[../../signals#django.db.models.signals|<code>post_save</code>]] signals aren't sent.
+
* 不会调用每个模型的 <code>save()</code> 方法,并且不会发送 [[../../signals#django.db.models.signals|pre_save]] [[../../signals#django.db.models.signals|post_save]] 信号。
* If updating a large number of columns in a large number of rows, the SQL generated can be very large. Avoid this by specifying a suitable <code>batch_size</code>.
+
* 如果更新大量行中的大量列,则生成的 SQL 可能非常大。 通过指定合适的 <code>batch_size</code> 来避免这种情况。
* Updating fields defined on multi-table inheritance ancestors will incur an extra query per ancestor.
+
* 更新定义在多表继承祖先上的字段将给每个祖先带来额外的查询。
* If <code>objs</code> contains duplicates, only the first one is updated.
+
* 如果 <code>objs</code> 包含重复项,则仅更新第一个。
  
The <code>batch_size</code> parameter controls how many objects are saved in a single
+
<code>batch_size</code> 参数控制在单个查询中保存的对象数量。 默认是批量更新所有对象,SQLite 和 Oracle 除外,它们对查询中使用的变量数量有限制。
query. The default is to update all objects in one batch, except for SQLite
 
and Oracle which have restrictions on the number of variables used in a query.
 
  
  
第3,124行: 第2,486行:
 
<div id="count" class="section">
 
<div id="count" class="section">
  
==== <code>count()</code> ====
+
==== count() ====
  
; <code>count</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">count</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
 
:  
 
:  
  
Returns an integer representing the number of objects in the database matching
+
返回一个整数,表示数据库中与 <code>QuerySet</code> 匹配的对象数。
the <code>QuerySet</code>.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,138行: 第2,499行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre># Returns the total number of entries in the database.
+
<syntaxhighlight lang="python"># Returns the total number of entries in the database.
 
Entry.objects.count()
 
Entry.objects.count()
  
 
# Returns the number of entries whose headline contains 'Lennon'
 
# Returns the number of entries whose headline contains 'Lennon'
Entry.objects.filter(headline__contains='Lennon').count()</pre>
+
Entry.objects.filter(headline__contains='Lennon').count()</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
A <code>count()</code> call performs a <code>SELECT COUNT(*)</code> behind the scenes, so you
+
<code>count()</code> 调用在幕后执行 <code>SELECT COUNT(*)</code>,因此您应该始终使用 <code>count()</code>,而不是将所有记录加载到 Python 对象中并调用 <code>len()</code>结果(除非您无论如何都需要将对象加载到内存中,在这种情况下 <code>len()</code> 会更快)。
should always use <code>count()</code> rather than loading all of the record into Python
 
objects and calling <code>len()</code> on the result (unless you need to load the
 
objects into memory anyway, in which case <code>len()</code> will be faster).
 
  
Note that if you want the number of items in a <code>QuerySet</code> and are also
+
请注意,如果您想要 <code>QuerySet</code> 中的项目数并且还从中检索模型实例(例如,通过对其进行迭代),则使用 <code>len(queryset)</code> 可能更有效t 会导致像 <code>count()</code> 这样的额外数据库查询。
retrieving model instances from it (for example, by iterating over it), it's
 
probably more efficient to use <code>len(queryset)</code> which won't cause an extra
 
database query like <code>count()</code> would.
 
  
  
第3,161行: 第2,516行:
 
<div id="in-bulk" class="section">
 
<div id="in-bulk" class="section">
  
==== <code>in_bulk()</code> ====
+
==== in_bulk() ====
  
; <code>in_bulk</code><span class="sig-paren">(</span>''<span class="n">id_list</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">field_name</span><span class="o">=</span><span class="default_value">'pk'</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">in_bulk</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">id_list</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">field_name</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">'pk'</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Takes a list of field values (<code>id_list</code>) and the <code>field_name</code> for those
+
获取字段值列表 (<code>id_list</code>) 和这些值的 <code>field_name</code>,并返回一个字典,将每个值映射到具有给定字段值的对象实例。 如果未提供 <code>id_list</code>,则返回查询集中的所有对象。 <code>field_name</code> 必须是唯一字段,默认为主键。
values, and returns a dictionary mapping each value to an instance of the
 
object with the given field value. If <code>id_list</code> isn't provided, all objects
 
in the queryset are returned. <code>field_name</code> must be a unique field, and it
 
defaults to the primary key.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,178行: 第2,529行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Blog.objects.in_bulk([1])
+
<syntaxhighlight lang="python">>>> Blog.objects.in_bulk([1])
{1: &lt;Blog: Beatles Blog&gt;}
+
{1: <Blog: Beatles Blog>}
&gt;&gt;&gt; Blog.objects.in_bulk([1, 2])
+
>>> Blog.objects.in_bulk([1, 2])
{1: &lt;Blog: Beatles Blog&gt;, 2: &lt;Blog: Cheddar Talk&gt;}
+
{1: <Blog: Beatles Blog>, 2: <Blog: Cheddar Talk>}
&gt;&gt;&gt; Blog.objects.in_bulk([])
+
>>> Blog.objects.in_bulk([])
 
{}
 
{}
&gt;&gt;&gt; Blog.objects.in_bulk()
+
>>> Blog.objects.in_bulk()
{1: &lt;Blog: Beatles Blog&gt;, 2: &lt;Blog: Cheddar Talk&gt;, 3: &lt;Blog: Django Weblog&gt;}
+
{1: <Blog: Beatles Blog>, 2: <Blog: Cheddar Talk>, 3: <Blog: Django Weblog>}
&gt;&gt;&gt; Blog.objects.in_bulk(['beatles_blog'], field_name='slug')
+
>>> Blog.objects.in_bulk(['beatles_blog'], field_name='slug')
{'beatles_blog': &lt;Blog: Beatles Blog&gt;}</pre>
+
{'beatles_blog': <Blog: Beatles Blog>}</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
If you pass <code>in_bulk()</code> an empty list, you'll get an empty dictionary.
+
如果你传递 <code>in_bulk()</code> 一个空列表,你会得到一个空字典。
  
  
第3,198行: 第2,549行:
 
<div id="iterator" class="section">
 
<div id="iterator" class="section">
  
==== <code>iterator()</code> ====
+
==== iterator() ====
  
; <code>iterator</code><span class="sig-paren">(</span>''<span class="n">chunk_size</span><span class="o">=</span><span class="default_value">2000</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">iterator</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">chunk_size</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">2000</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Evaluates the <code>QuerySet</code> (by performing the query) and returns an iterator
+
评估 <code>QuerySet</code>(通过执行查询)并返回一个迭代器(参见 <span id="index-1" class="target"></span>[https://www.python.org/dev/peps/pep-0234 PEP 234])。 <code>QuerySet</code> 通常在内部缓存其结果,以便重复评估不会导致额外的查询。 相比之下, <code>iterator()</code> 会直接读取结果,不会在 <code>QuerySet</code> 级别做任何缓存(在内部,默认迭代器调用 <code>iterator()</code> 并缓存返回值)。 对于返回大量只需要访问一次的对象的 <code>QuerySet</code>,这可以带来更好的性能并显着减少内存。
(see <span id="index-1" class="target"></span>[https://www.python.org/dev/peps/pep-0234 '''PEP 234''']) over the results. A <code>QuerySet</code> typically caches its results
 
internally so that repeated evaluations do not result in additional queries. In
 
contrast, <code>iterator()</code> will read results directly, without doing any caching
 
at the <code>QuerySet</code> level (internally, the default iterator calls <code>iterator()</code>
 
and caches the return value). For a <code>QuerySet</code> which returns a large number of
 
objects that you only need to access once, this can result in better
 
performance and a significant reduction in memory.
 
  
Note that using <code>iterator()</code> on a <code>QuerySet</code> which has already been
+
请注意,在已经计算过的 <code>QuerySet</code> 上使用 <code>iterator()</code> 将强制它再次计算,重复查询。
evaluated will force it to evaluate again, repeating the query.
 
  
Also, use of <code>iterator()</code> causes previous <code>prefetch_related()</code> calls to be
+
此外,使用 <code>iterator()</code> 会导致之前的 <code>prefetch_related()</code> 调用被忽略,因为这两个优化一起使用没有意义。
ignored since these two optimizations do not make sense together.
 
  
Depending on the database backend, query results will either be loaded all at
+
根据数据库后端,查询结果将被一次性加载或使用服务器端的游标从数据库中流转。
once or streamed from the database using server-side cursors.
 
  
 
<div id="with-server-side-cursors" class="section">
 
<div id="with-server-side-cursors" class="section">
  
===== With server-side cursors =====
+
===== 使用服务器端游标 =====
  
Oracle and [[../../databases#postgresql-server-side-cursors|<span class="std std-ref">PostgreSQL</span>]] use server-side
+
Oracle [[../../databases#postgresql-server-side-cursors|PostgreSQL]] 使用服务器端游标从数据库中流式传输结果,而无需将整个结果集加载到内存中。
cursors to stream results from the database without loading the entire result
 
set into memory.
 
  
The Oracle database driver always uses server-side cursors.
+
Oracle 数据库驱动程序总是使用服务器端的游标。
  
With server-side cursors, the <code>chunk_size</code> parameter specifies the number of
+
对于服务器端游标,<code>chunk_size</code> 参数指定要在数据库驱动程序级别缓存的结果数。 获取更大的块会减少数据库驱动程序和数据库之间的往返次数,但会消耗内存。
results to cache at the database driver level. Fetching bigger chunks
 
diminishes the number of round trips between the database driver and the
 
database, at the expense of memory.
 
  
On PostgreSQL, server-side cursors will only be used when the
+
PostgreSQL 上,服务器端游标只会在以下情况下使用 [[#id8|:设置:`DISABLE_SERVER_SIDE_CURSORS `]] 设置是<code>False</code> . 如果您使用以事务池模式配置的连接池,请阅读 [[../../databases#transaction-pooling-server-side-cursors|事务池和服务器端游标]] 。 禁用服务器端游标时,行为与不支持服务器端游标的数据库相同。
[[../../settings#std-setting-DATABASE-DISABLE_SERVER_SIDE_CURSORS|<code>DISABLE_SERVER_SIDE_CURSORS</code>]]
 
setting is <code>False</code>. Read [[../../databases#transaction-pooling-server-side-cursors|<span class="std std-ref">Transaction pooling and server-side cursors</span>]] if
 
you're using a connection pooler configured in transaction pooling mode. When
 
server-side cursors are disabled, the behavior is the same as databases that
 
don't support server-side cursors.
 
  
  
第3,247行: 第2,578行:
 
<div id="without-server-side-cursors" class="section">
 
<div id="without-server-side-cursors" class="section">
  
===== Without server-side cursors =====
+
===== 没有服务器端游标 =====
  
MySQL doesn't support streaming results, hence the Python database driver loads
+
MySQL 不支持流式结果,因此 Python 数据库驱动程序将整个结果集加载到内存中。 然后,数据库适配器使用 <span id="index-2" class="target"></span>[https://www.python.org/dev/peps/pep-0249 PEP 249] 中定义的 <code>fetchmany()</code> 方法将结果集转换为 Python 行对象。
the entire result set into memory. The result set is then transformed into
 
Python row objects by the database adapter using the <code>fetchmany()</code> method
 
defined in <span id="index-2" class="target"></span>[https://www.python.org/dev/peps/pep-0249 '''PEP 249'''].
 
  
SQLite can fetch results in batches using <code>fetchmany()</code>, but since SQLite
+
SQLite 可以使用 <code>fetchmany()</code> 批量获取结果,但由于 SQLite 不提供连接内查询之间的隔离,因此在写入被迭代的表时要小心。 有关详细信息,请参阅使用 QuerySet.iterator() [[../../databases#sqlite-isolation|时的]] 隔离。
doesn't provide isolation between queries within a connection, be careful when
 
writing to the table being iterated over. See [[../../databases#sqlite-isolation|<span class="std std-ref">Isolation when using QuerySet.iterator()</span>]] for
 
more information.
 
  
The <code>chunk_size</code> parameter controls the size of batches Django retrieves from
+
<code>chunk_size</code> 参数控制 Django 从数据库驱动程序中检索的批次大小。 较大的批处理减少了与数据库驱动程序通信的开销,但代价是内存消耗略有增加。
the database driver. Larger batches decrease the overhead of communicating with
 
the database driver at the expense of a slight increase in memory consumption.
 
  
The default value of <code>chunk_size</code>, 2000, comes from [https://www.postgresql.org/message-id/4D2F2C71.8080805%40dndg.it a calculation on the
+
<code>chunk_size</code> 的默认值,2000,来自 psycopg 邮件列表 [https://www.postgresql.org/message-id/4D2F2C71.8080805%40dndg.it 上的] 计算:
psycopg mailing list]:
 
  
 
<blockquote><div>
 
<blockquote><div>
  
Assuming rows of 10-20 columns with a mix of textual and numeric data, 2000
+
假设行数为 10-20 列,文字数据和数字数据混合,2000 要取不到 100KB 的数据,这似乎是一个很好的折中方案,在传输的行数和提前退出循环时丢弃的数据之间。
is going to fetch less than 100KB of data, which seems a good compromise
 
between the number of rows transferred and the data discarded if the loop
 
is exited early.
 
  
  
第3,277行: 第2,596行:
 
<div class="versionchanged">
 
<div class="versionchanged">
  
Support for result streaming on SQLite was added.
+
<span class="versionmodified changed"> 2.2 版更改:</span> 添加了对 SQLite 上的结果流的支持。
  
  
第3,287行: 第2,606行:
 
<div id="latest" class="section">
 
<div id="latest" class="section">
  
==== <code>latest()</code> ====
+
==== latest() ====
  
; <code>latest</code><span class="sig-paren">(</span>''<span class="o">*</span><span class="n">fields</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">latest</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">fields</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Returns the latest object in the table based on the given field(s).
+
根据给定的字段,返回表中最新的对象。
  
This example returns the latest <code>Entry</code> in the table, according to the
+
本示例根据 <code>pub_date</code> 字段返回表中最新的 <code>Entry</code>
<code>pub_date</code> field:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,301行: 第2,619行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.latest('pub_date')</pre>
+
<syntaxhighlight lang="python">Entry.objects.latest('pub_date')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
You can also choose the latest based on several fields. For example, to select
+
您还可以根据多个字段选择最新的。 例如,当两个条目具有相同的 <code>pub_date</code> 时,选择 <code>Entry</code> 与最早的 <code>expire_date</code>
the <code>Entry</code> with the earliest <code>expire_date</code> when two entries have the same
 
<code>pub_date</code>:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,314行: 第2,630行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.latest('pub_date', '-expire_date')</pre>
+
<syntaxhighlight lang="python">Entry.objects.latest('pub_date', '-expire_date')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The negative sign in <code>'-expire_date'</code> means to sort <code>expire_date</code> in
+
<code>'-expire_date'</code>中的负号表示按''降序''对<code>expire_date</code>进行排序。 由于<code>latest()</code>得到最后的结果,所以选择了<code>expire_date</code>最早的<code>Entry</code>
''descending'' order. Since <code>latest()</code> gets the last result, the <code>Entry</code> with
 
the earliest <code>expire_date</code> is selected.
 
  
If your model's [[../../../topics/db/models#meta-options|<span class="std std-ref">Meta</span>]] specifies
+
如果您模型的 [[../../../topics/db/models#meta-options|Meta]] 指定 [[../options#django.db.models.Options|get_latest_by]],则您可以省略 <code>earliest()</code> <code>latest()</code> 的任何参数。 默认情况下将使用 [[../options#django.db.models.Options|get_latest_by]] 中指定的字段。
[[../options#django.db.models.Options|<code>get_latest_by</code>]], you can omit any arguments to
 
<code>earliest()</code> or <code>latest()</code>. The fields specified in
 
[[../options#django.db.models.Options|<code>get_latest_by</code>]] will be used by default.
 
  
Like [[#django.db.models.query.QuerySet.get|<code>get()</code>]], <code>earliest()</code> and <code>latest()</code> raise
+
[[#django.db.models.query.QuerySet.get|get()]]<code>earliest()</code> <code>latest()</code> 引发 [[../instances#django.db.models.Model|DoesNotExist]] 如果没有具有给定参数的对象。
[[../instances#django.db.models.Model|<code>DoesNotExist</code>]] if there is no object with the
 
given parameters.
 
  
Note that <code>earliest()</code> and <code>latest()</code> exist purely for convenience and
+
请注意,<code>earliest()</code> <code>latest()</code> 的存在纯粹是为了方便和可读性。
readability.
 
  
 
<div class="admonition-earliest-and-latest-may-return-instances-with-null-dates admonition">
 
<div class="admonition-earliest-and-latest-may-return-instances-with-null-dates admonition">
  
<code>earliest()</code> and <code>latest()</code> may return instances with null dates.
+
<code>earliest()</code> <code>latest()</code> 可能返回具有空日期的实例。
  
Since ordering is delegated to the database, results on fields that allow
+
由于排序委托给数据库,如果您使用不同的数据库,则允许空值的字段的结果可能会以不同的方式排序。 例如,PostgreSQL 和 MySQL 对空值进行排序,就好像它们高于非空值一样,而 SQLite 则相反。
null values may be ordered differently if you use different databases. For
 
example, PostgreSQL and MySQL sort null values as if they are higher than
 
non-null values, while SQLite does the opposite.
 
  
You may want to filter out null values:
+
您可能希望过滤掉空值:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,350行: 第2,655行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(pub_date__isnull=False).latest('pub_date')</pre>
+
<syntaxhighlight lang="python">Entry.objects.filter(pub_date__isnull=False).latest('pub_date')</syntaxhighlight>
  
 
</div>
 
</div>
第3,361行: 第2,666行:
 
<div id="earliest" class="section">
 
<div id="earliest" class="section">
  
==== <code>earliest()</code> ====
+
==== earliest() ====
  
; <code>earliest</code><span class="sig-paren">(</span>''<span class="o">*</span><span class="n">fields</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">earliest</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">fields</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Works otherwise like [[#django.db.models.query.QuerySet.latest|<code>latest()</code>]] except
+
除了方向改变外,其他方式与 [[#django.db.models.query.QuerySet.latest|latest()]] 类似。
the direction is changed.
 
  
  
第3,373行: 第2,677行:
 
<div id="first" class="section">
 
<div id="first" class="section">
  
==== <code>first()</code> ====
+
==== first() ====
  
; <code>first</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">first</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
 
:  
 
:  
  
Returns the first object matched by the queryset, or <code>None</code> if there
+
返回查询集匹配的第一个对象,如果没有匹配的对象,则返回 <code>None</code>。 如果 <code>QuerySet</code> 没有定义排序,那么查询集会自动按主键排序。 这可能会影响聚合结果,如 [[../../../topics/db/aggregation#aggregation-ordering-interaction|与默认排序或 order_by()]] 的交互中所述。
is no matching object. If the <code>QuerySet</code> has no ordering defined, then the
 
queryset is automatically ordered by the primary key. This can affect
 
aggregation results as described in [[../../../topics/db/aggregation#aggregation-ordering-interaction|<span class="std std-ref">与默认排序或 order_by() 交互</span>]].
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,389行: 第2,690行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>p = Article.objects.order_by('title', 'pub_date').first()</pre>
+
<syntaxhighlight lang="python">p = Article.objects.order_by('title', 'pub_date').first()</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Note that <code>first()</code> is a convenience method, the following code sample is
+
注意 <code>first()</code> 是一个方便的方法,下面的代码示例相当于上面的例子:
equivalent to the above example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,401行: 第2,701行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>try:
+
<syntaxhighlight lang="python">try:
 
     p = Article.objects.order_by('title', 'pub_date')[0]
 
     p = Article.objects.order_by('title', 'pub_date')[0]
 
except IndexError:
 
except IndexError:
     p = None</pre>
+
     p = None</syntaxhighlight>
  
 
</div>
 
</div>
第3,413行: 第2,713行:
 
<div id="last" class="section">
 
<div id="last" class="section">
  
==== <code>last()</code> ====
+
==== last() ====
  
; <code>last</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">last</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
 
:  
 
:  
  
Works like [[#django.db.models.query.QuerySet.first|<code>first()</code>]], but returns the last object in the queryset.
+
[[#django.db.models.query.QuerySet.first|first()]] 一样工作,但返回查询集中的最后一个对象。
  
  
第3,424行: 第2,724行:
 
<div id="aggregate" class="section">
 
<div id="aggregate" class="section">
  
==== <code>aggregate()</code> ====
+
==== aggregate() ====
  
; <code>aggregate</code><span class="sig-paren">(</span>''<span class="o">*</span><span class="n">args</span>'', ''<span class="o">**</span><span class="n">kwargs</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">aggregate</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">args</span></span>'', ''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Returns a dictionary of aggregate values (averages, sums, etc.) calculated over
+
返回在 <code>QuerySet</code> 上计算的聚合值(平均值、总和等)的字典。 <code>aggregate()</code> 的每个参数指定一个值,该值将包含在返回的字典中。
the <code>QuerySet</code>. Each argument to <code>aggregate()</code> specifies a value that will
 
be included in the dictionary that is returned.
 
  
The aggregation functions that are provided by Django are described in
+
Django 提供的聚合函数在下面的 [[#id41|Aggregation Functions]] 中描述。 由于聚合也是 [[../expressions|查询表达式]] ,您可以将聚合与其他聚合或值组合以创建复杂的聚合。
[[#id5|Aggregation Functions]] below. Since aggregates are also [[../expressions|<span class="doc">query
 
expressions</span>]], you may combine aggregates with other
 
aggregates or values to create complex aggregates.
 
  
Aggregates specified using keyword arguments will use the keyword as the name
+
使用关键字参数指定的聚合将使用关键字作为注释的名称。 匿名参数将根据聚合函数的名称和正在聚合的模型字段为它们生成一个名称。 复杂聚合不能使用匿名参数,必须将关键字参数指定为别名。
for the annotation. Anonymous arguments will have a name generated for them
 
based upon the name of the aggregate function and the model field that is being
 
aggregated. Complex aggregates cannot use anonymous arguments and must specify
 
a keyword argument as an alias.
 
  
For example, when you are working with blog entries, you may want to know the
+
例如,当您处理博客条目时,您可能想知道贡献了博客条目的作者数量:
number of authors that have contributed blog entries:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,451行: 第2,741行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; from django.db.models import Count
+
<syntaxhighlight lang="python">>>> from django.db.models import Count
&gt;&gt;&gt; q = Blog.objects.aggregate(Count('entry'))
+
>>> q = Blog.objects.aggregate(Count('entry'))
{'entry__count': 16}</pre>
+
{'entry__count': 16}</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
By using a keyword argument to specify the aggregate function, you can
+
通过使用关键字参数指定聚合函数,您可以控制返回的聚合值的名称:
control the name of the aggregation value that is returned:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,465行: 第2,754行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; q = Blog.objects.aggregate(number_of_entries=Count('entry'))
+
<syntaxhighlight lang="python">>>> q = Blog.objects.aggregate(number_of_entries=Count('entry'))
{'number_of_entries': 16}</pre>
+
{'number_of_entries': 16}</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
For an in-depth discussion of aggregation, see [[../../../topics/db/aggregation|<span class="doc">the topic guide on
+
有关聚合的深入讨论,请参阅 [[../../../topics/db/aggregation|有关聚合的主题指南]]
Aggregation</span>]].
 
  
  
第3,478行: 第2,766行:
 
<div id="exists" class="section">
 
<div id="exists" class="section">
  
==== <code>exists()</code> ====
+
==== exists() ====
  
; <code>exists</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">exists</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
 
:  
 
:  
  
Returns <code>True</code> if the [[#django.db.models.query.QuerySet|<code>QuerySet</code>]] contains any results, and <code>False</code>
+
如果 [[#django.db.models.query.QuerySet|QuerySet]] 包含任何结果,则返回 <code>True</code>,否则返回 <code>False</code>。 这试图以最简单和最快的方式执行查询,但它 ''确实'' 执行与普通 [[#django.db.models.query.QuerySet|QuerySet]] 查询几乎相同的查询。
if not. This tries to perform the query in the simplest and fastest way
 
possible, but it ''does'' execute nearly the same query as a normal
 
[[#django.db.models.query.QuerySet|<code>QuerySet</code>]] query.
 
  
[[#django.db.models.query.QuerySet.exists|<code>exists()</code>]] is useful for searches relating to both
+
[[#django.db.models.query.QuerySet.exists|exists()]] 可用于与 [[#django.db.models.query.QuerySet|QuerySet]] 中的对象成员资格和 [[#django.db.models.query.QuerySet|QuerySet]] 中任何对象的存在相关的搜索,特别是在大 [[#django.db.models.query.QuerySet|查询集]]
object membership in a [[#django.db.models.query.QuerySet|<code>QuerySet</code>]] and to the existence of any objects in
 
a [[#django.db.models.query.QuerySet|<code>QuerySet</code>]], particularly in the context of a large [[#django.db.models.query.QuerySet|<code>QuerySet</code>]].
 
  
The most efficient method of finding whether a model with a unique field
+
查找模型是否具有唯一字段的最有效方法(例如 <code>primary_key</code>) [[#django.db.models.query.QuerySet|QuerySet]] 的成员是:
(e.g. <code>primary_key</code>) is a member of a [[#django.db.models.query.QuerySet|<code>QuerySet</code>]] is:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,499行: 第2,781行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>entry = Entry.objects.get(pk=123)
+
<syntaxhighlight lang="python">entry = Entry.objects.get(pk=123)
 
if some_queryset.filter(pk=entry.pk).exists():
 
if some_queryset.filter(pk=entry.pk).exists():
     print(&quot;Entry contained in queryset&quot;)</pre>
+
     print("Entry contained in queryset")</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Which will be faster than the following which requires evaluating and iterating
+
这将比以下需要评估和迭代整个查询集的更快:
through the entire queryset:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,513行: 第2,794行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>if entry in some_queryset:
+
<syntaxhighlight lang="python">if entry in some_queryset:
   print(&quot;Entry contained in QuerySet&quot;)</pre>
+
   print("Entry contained in QuerySet")</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
And to find whether a queryset contains any items:
+
并查找查询集是否包含任何项目:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,525行: 第2,806行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>if some_queryset.exists():
+
<syntaxhighlight lang="python">if some_queryset.exists():
     print(&quot;There is at least one object in some_queryset&quot;)</pre>
+
     print("There is at least one object in some_queryset")</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Which will be faster than:
+
这将比:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,537行: 第2,818行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>if some_queryset:
+
<syntaxhighlight lang="python">if some_queryset:
     print(&quot;There is at least one object in some_queryset&quot;)</pre>
+
     print("There is at least one object in some_queryset")</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
... but not by a large degree (hence needing a large queryset for efficiency
+
……但不是很大(因此需要一个大的查询集来提高效率)。
gains).
 
  
Additionally, if a <code>some_queryset</code> has not yet been evaluated, but you know
+
此外,如果 <code>some_queryset</code> 尚未被评估,但您知道它会在某个时刻被评估,那么使用 <code>some_queryset.exists()</code> 将完成更多的整体工作(一个存在检查的查询加上一个额外的一到稍后检索结果),而不是简单地使用 <code>bool(some_queryset)</code>,后者检索结果,然后检查是否有任何返回。
that it will be at some point, then using <code>some_queryset.exists()</code> will do
 
more overall work (one query for the existence check plus an extra one to later
 
retrieve the results) than simply using <code>bool(some_queryset)</code>, which
 
retrieves the results and then checks if any were returned.
 
  
  
第3,556行: 第2,832行:
 
<div id="update" class="section">
 
<div id="update" class="section">
  
==== <code>update()</code> ====
+
==== update() ====
  
; <code>update</code><span class="sig-paren">(</span>''<span class="o">**</span><span class="n">kwargs</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">update</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Performs an SQL update query for the specified fields, and returns
+
对指定的字段执行 SQL 更新查询,并返回匹配的行数(如果有些行已经有了新的值,则可能不等于更新的行数)。
the number of rows matched (which may not be equal to the number of rows
 
updated if some rows already have the new value).
 
  
For example, to turn comments off for all blog entries published in 2010,
+
例如,要关闭 2010 年发布的所有博客条目的评论,您可以执行以下操作:
you could do this:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,572行: 第2,845行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Entry.objects.filter(pub_date__year=2010).update(comments_on=False)</pre>
+
<syntaxhighlight lang="python">>>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
(This assumes your <code>Entry</code> model has fields <code>pub_date</code> and <code>comments_on</code>.)
+
(这假设您的 <code>Entry</code> 模型具有字段 <code>pub_date</code> <code>comments_on</code>。)
  
You can update multiple fields — there's no limit on how many. For example,
+
您可以更新多个字段 - 数量没有限制。 例如,这里我们更新 <code>comments_on</code> <code>headline</code> 字段:
here we update the <code>comments_on</code> and <code>headline</code> fields:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,586行: 第2,858行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Entry.objects.filter(pub_date__year=2010).update(comments_on=False, headline='This is old')</pre>
+
<syntaxhighlight lang="python">>>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False, headline='This is old')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The <code>update()</code> method is applied instantly, and the only restriction on the
+
<code>update()</code> 方法是即时应用的,更新的 [[#django.db.models.query.QuerySet|QuerySet]] 唯一的限制是它只能更新模型主表中的列,不能更新相关模型。 你不能这样做,例如:
[[#django.db.models.query.QuerySet|<code>QuerySet</code>]] that is updated is that it can only update columns in the
 
model's main table, not on related models. You can't do this, for example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,599行: 第2,869行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Entry.objects.update(blog__name='foo') # Won't work!</pre>
+
<syntaxhighlight lang="python">>>> Entry.objects.update(blog__name='foo') # Won't work!</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Filtering based on related fields is still possible, though:
+
不过,仍然可以根据相关字段进行过滤:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,610行: 第2,880行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Entry.objects.filter(blog__id=1).update(comments_on=True)</pre>
+
<syntaxhighlight lang="python">>>> Entry.objects.filter(blog__id=1).update(comments_on=True)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
You cannot call <code>update()</code> on a [[#django.db.models.query.QuerySet|<code>QuerySet</code>]] that has had a slice taken
+
您不能在已获取切片或无法再过滤的 [[#django.db.models.query.QuerySet|QuerySet]] 上调用 <code>update()</code>
or can otherwise no longer be filtered.
 
  
The <code>update()</code> method returns the number of affected rows:
+
<code>update()</code> 方法返回受影响的行数:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,624行: 第2,893行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Entry.objects.filter(id=64).update(comments_on=True)
+
<syntaxhighlight lang="python">>>> Entry.objects.filter(id=64).update(comments_on=True)
 
1
 
1
  
&gt;&gt;&gt; Entry.objects.filter(slug='nonexistent-slug').update(comments_on=True)
+
>>> Entry.objects.filter(slug='nonexistent-slug').update(comments_on=True)
 
0
 
0
  
&gt;&gt;&gt; Entry.objects.filter(pub_date__year=2010).update(comments_on=False)
+
>>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False)
132</pre>
+
132</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
If you're just updating a record and don't need to do anything with the model
+
如果你只是更新一条记录并且不需要对模型对象做任何事情,最有效的方法是调用 <code>update()</code>,而不是将模型对象加载到内存中。 例如,不要这样做:
object, the most efficient approach is to call <code>update()</code>, rather than
 
loading the model object into memory. For example, instead of doing this:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,644行: 第2,911行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>e = Entry.objects.get(id=10)
+
<syntaxhighlight lang="python">e = Entry.objects.get(id=10)
 
e.comments_on = False
 
e.comments_on = False
e.save()</pre>
+
e.save()</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
...do this:
+
…做这个:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,657行: 第2,924行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(id=10).update(comments_on=False)</pre>
+
<syntaxhighlight lang="python">Entry.objects.filter(id=10).update(comments_on=False)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Using <code>update()</code> also prevents a race condition wherein something might
+
使用 <code>update()</code> 还可以防止竞争条件,即在加载对象和调用 <code>save()</code> 之间的短时间内,数据库中的某些内容可能会发生变化。
change in your database in the short period of time between loading the object
 
and calling <code>save()</code>.
 
  
Finally, realize that <code>update()</code> does an update at the SQL level and, thus,
+
最后,意识到 <code>update()</code> SQL 级别进行更新,因此不会在您的模型上调用任何 <code>save()</code> 方法,也不会发出 [[../../signals#django.db.models.signals|pre_save]] [ X169X]post_save 信号(这是调用 [[../instances#django.db.models.Model|Model.save()]] 的结果)。 如果要更新具有自定义 [[../instances#django.db.models.Model|save()]] 方法的模型的一堆记录,请遍历它们并调用 [[../instances#django.db.models.Model|save()]],如下所示:
does not call any <code>save()</code> methods on your models, nor does it emit the
 
[[../../signals#django.db.models.signals|<code>pre_save</code>]] or
 
[[../../signals#django.db.models.signals|<code>post_save</code>]] signals (which are a consequence of
 
calling [[../instances#django.db.models.Model|<code>Model.save()</code>]]). If you want to
 
update a bunch of records for a model that has a custom
 
[[../instances#django.db.models.Model|<code>save()</code>]] method, loop over them and call
 
[[../instances#django.db.models.Model|<code>save()</code>]], like this:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,679行: 第2,937行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>for e in Entry.objects.filter(pub_date__year=2010):
+
<syntaxhighlight lang="python">for e in Entry.objects.filter(pub_date__year=2010):
 
     e.comments_on = False
 
     e.comments_on = False
     e.save()</pre>
+
     e.save()</syntaxhighlight>
  
 
</div>
 
</div>
第3,690行: 第2,948行:
 
<div id="delete" class="section">
 
<div id="delete" class="section">
  
==== <code>delete()</code> ====
+
==== delete() ====
  
; <code>delete</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">delete</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
 
:  
 
:  
  
Performs an SQL delete query on all rows in the [[#django.db.models.query.QuerySet|<code>QuerySet</code>]] and
+
[[#django.db.models.query.QuerySet|QuerySet]] 中的所有行执行 SQL 删除查询,并返回删除的对象数和包含每种对象类型删除数的字典。
returns the number of objects deleted and a dictionary with the number of
 
deletions per object type.
 
  
The <code>delete()</code> is applied instantly. You cannot call <code>delete()</code> on a
+
<code>delete()</code> 立即应用。 您不能在已获取切片或无法再过滤的 [[#django.db.models.query.QuerySet|QuerySet]] 上调用 <code>delete()</code>
[[#django.db.models.query.QuerySet|<code>QuerySet</code>]] that has had a slice taken or can otherwise no longer be
 
filtered.
 
  
For example, to delete all the entries in a particular blog:
+
例如,要删除特定博客中的所有条目:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,709行: 第2,963行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; b = Blog.objects.get(pk=1)
+
<syntaxhighlight lang="python">>>> b = Blog.objects.get(pk=1)
  
 
# Delete all the entries belonging to this Blog.
 
# Delete all the entries belonging to this Blog.
&gt;&gt;&gt; Entry.objects.filter(blog=b).delete()
+
>>> Entry.objects.filter(blog=b).delete()
(4, {'weblog.Entry': 2, 'weblog.Entry_authors': 2})</pre>
+
(4, {'weblog.Entry': 2, 'weblog.Entry_authors': 2})</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
By default, Django's [[../fields#django.db.models|<code>ForeignKey</code>]] emulates the SQL
+
默认情况下,Django 的 [[../fields#django.db.models|ForeignKey]] 模拟 SQL 约束 <code>ON DELETE CASCADE</code> — 换句话说,任何外键指向要删除的对象的对象都将被删除。 例如:
constraint <code>ON DELETE CASCADE</code> — in other words, any objects with foreign
 
keys pointing at the objects to be deleted will be deleted along with them.
 
For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,727行: 第2,978行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; blogs = Blog.objects.all()
+
<syntaxhighlight lang="python">>>> blogs = Blog.objects.all()
  
 
# This will delete all Blogs and all of their Entry objects.
 
# This will delete all Blogs and all of their Entry objects.
&gt;&gt;&gt; blogs.delete()
+
>>> blogs.delete()
(5, {'weblog.Blog': 1, 'weblog.Entry': 2, 'weblog.Entry_authors': 2})</pre>
+
(5, {'weblog.Blog': 1, 'weblog.Entry': 2, 'weblog.Entry_authors': 2})</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
这种约束行为通过 [[../fields#django.db.models|<code>ForeignKey</code>]] 的 [[../fields#django.db.models.ForeignKey|<code>on_delete</code>]] 参数定义。
+
此级联行为可通过 [[../fields#django.db.models|ForeignKey]] 的 [[../fields#django.db.models.ForeignKey|on_delete]] 参数进行自定义。
  
The <code>delete()</code> method does a bulk delete and does not call any <code>delete()</code>
+
<code>delete()</code> 方法执行批量删除,并且不会在您的模型上调用任何 <code>delete()</code> 方法。 但是,它确实为所有已删除的对象(包括级联删除)发出 [[../../signals#django.db.models.signals|pre_delete]] [[../../signals#django.db.models.signals|post_delete]] 信号。
methods on your models. It does, however, emit the
 
[[../../signals#django.db.models.signals|<code>pre_delete</code>]] and
 
[[../../signals#django.db.models.signals|<code>post_delete</code>]] signals for all deleted objects
 
(including cascaded deletions).
 
  
Django needs to fetch objects into memory to send signals and handle cascades.
+
Django 需要将对象提取到内存中以发送信号和处理级联。 但是,如果没有级联和信号,那么 Django 可能会采用快速路径并删除对象而不提取到内存中。 对于大型删除,这会导致显着减少内存使用。 执行查询的数量也可以减少。
However, if there are no cascades and no signals, then Django may take a
 
fast-path and delete objects without fetching into memory. For large
 
deletes this can result in significantly reduced memory usage. The amount of
 
executed queries can be reduced, too.
 
  
ForeignKeys which are set to [[../fields#django.db.models.ForeignKey|<code>on_delete</code>]]
+
设置为 [[../fields#django.db.models.ForeignKey|on_delete]] <code>DO_NOTHING</code> 的外键不会阻止在删除时采用快速路径。
<code>DO_NOTHING</code> do not prevent taking the fast-path in deletion.
 
  
Note that the queries generated in object deletion is an implementation
+
需要注意的是,对象删除中产生的查询是一个实现细节,可能会发生变化。
detail subject to change.
 
  
  
第3,760行: 第3,001行:
 
<div id="as-manager" class="section">
 
<div id="as-manager" class="section">
  
==== <code>as_manager()</code> ====
+
==== as_manager() ====
  
; ''classmethod'' <code>as_manager</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; ''<span class="pre">classmethod</span>'' <span class="sig-name descname"><span class="pre">as_manager</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
 
:  
 
:  
  
Class method that returns an instance of [[../../../topics/db/managers#django.db.models|<code>Manager</code>]]
+
返回 [[../../../topics/db/managers#django.db.models|Manager]] 实例和 <code>QuerySet</code> 方法副本的类方法。 有关更多详细信息,请参阅 [[../../../topics/db/managers#create-manager-with-queryset-methods|使用 QuerySet 方法创建管理器]]
with a copy of the <code>QuerySet</code>’s methods. See
 
[[../../../topics/db/managers#create-manager-with-queryset-methods|<span class="std std-ref">创建带有 QuerySet 方法的管理器</span>]] for more details.
 
  
  
第3,773行: 第3,012行:
 
<div id="explain" class="section">
 
<div id="explain" class="section">
  
==== <code>explain()</code> ====
+
==== explain() ====
  
 
<div class="versionadded">
 
<div class="versionadded">
  
 +
<span class="versionmodified added">2.1 版中的新功能。</span>
  
  
 
</div>
 
</div>
; <code>explain</code><span class="sig-paren">(</span>''<span class="n">format</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="o">**</span><span class="n">options</span>''<span class="sig-paren">)</span>
+
; <span class="sig-name descname"><span class="pre">explain</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">format</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">options</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Returns a string of the <code>QuerySet</code>’s execution plan, which details how the
+
返回 <code>QuerySet</code> 的执行计划的字符串,它详细说明了数据库将如何执行查询,包括将使用的任何索引或连接。 了解这些细节可能会帮助您提高慢查询的性能。
database would execute the query, including any indexes or joins that would be
 
used. Knowing these details may help you improve the performance of slow
 
queries.
 
  
For example, when using PostgreSQL:
+
例如,当使用 PostgreSQL 时:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,794行: 第3,031行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; print(Blog.objects.filter(title='My Blog').explain())
+
<syntaxhighlight lang="python">>>> print(Blog.objects.filter(title='My Blog').explain())
 
Seq Scan on blog  (cost=0.00..35.50 rows=10 width=12)
 
Seq Scan on blog  (cost=0.00..35.50 rows=10 width=12)
   Filter: (title = 'My Blog'::bpchar)</pre>
+
   Filter: (title = 'My Blog'::bpchar)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The output differs significantly between databases.
+
不同数据库之间的输出有很大的不同。
  
<code>explain()</code> is supported by all built-in database backends except Oracle
+
<code>explain()</code> 被除 Oracle 之外的所有内置数据库后端支持,因为那里的实现并不简单。
because an implementation there isn't straightforward.
 
  
The <code>format</code> parameter changes the output format from the databases's default,
+
<code>format</code> 参数改变了数据库默认的输出格式,通常是基于文本的。 PostgreSQL 支持 <code>'TEXT'</code><code>'JSON'</code><code>'YAML'</code> <code>'XML'</code>MySQL 支持 <code>'TEXT'</code>(也称为 <code>'TRADITIONAL'</code>)和 <code>'JSON'</code>
usually text-based. PostgreSQL supports <code>'TEXT'</code>, <code>'JSON'</code>, <code>'YAML'</code>, and
 
<code>'XML'</code>. MySQL supports <code>'TEXT'</code> (also called <code>'TRADITIONAL'</code>) and
 
<code>'JSON'</code>.
 
  
Some databases accept flags that can return more information about the query.
+
某些数据库接受可以返回有关查询的更多信息的标志。 将这些标志作为关键字参数传递。 例如,当使用 PostgreSQL 时:
Pass these flags as keyword arguments. For example, when using PostgreSQL:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,818行: 第3,050行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; print(Blog.objects.filter(title='My Blog').explain(verbose=True))
+
<syntaxhighlight lang="python">>>> print(Blog.objects.filter(title='My Blog').explain(verbose=True))
 
Seq Scan on public.blog  (cost=0.00..35.50 rows=10 width=12) (actual time=0.004..0.004 rows=10 loops=1)
 
Seq Scan on public.blog  (cost=0.00..35.50 rows=10 width=12) (actual time=0.004..0.004 rows=10 loops=1)
 
   Output: id, title
 
   Output: id, title
 
   Filter: (blog.title = 'My Blog'::bpchar)
 
   Filter: (blog.title = 'My Blog'::bpchar)
 
Planning time: 0.064 ms
 
Planning time: 0.064 ms
Execution time: 0.058 ms</pre>
+
Execution time: 0.058 ms</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
On some databases, flags may cause the query to be executed which could have
+
在某些数据库上,标志可能会导致执行查询,这可能会对您的数据库产生不利影响。 例如,如果有触发器或函数被调用,PostgreSQL 的 <code>ANALYZE</code> 标志可能会导致数据更改,即使对于 <code>SELECT</code> 查询也是如此。
adverse effects on your database. For example, PostgreSQL's <code>ANALYZE</code> flag
 
could result in changes to data if there are triggers or if a function is
 
called, even for a <code>SELECT</code> query.
 
  
  
第3,839行: 第3,068行:
 
<div id="field-lookups" class="section">
 
<div id="field-lookups" class="section">
  
<span id="id4"></span>
+
<span id="id10"></span>
=== <code>Field</code> lookups ===
+
=== Field 查找 ===
  
Field lookups are how you specify the meat of an SQL <code>WHERE</code> clause. They're
+
字段查找是您指定 SQL <code>WHERE</code> 子句内容的方式。 它们被指定为 <code>QuerySet</code> 方法 [[#django.db.models.query.QuerySet.filter|filter()]][[#django.db.models.query.QuerySet.exclude|exclude()]] [[#django.db.models.query.QuerySet.get|get()]] 的关键字参数。
specified as keyword arguments to the <code>QuerySet</code> methods [[#django.db.models.query.QuerySet.filter|<code>filter()</code>]],
 
[[#django.db.models.query.QuerySet.exclude|<code>exclude()</code>]] and [[#django.db.models.query.QuerySet.get|<code>get()</code>]].
 
  
For an introduction, see [[../../../topics/db/queries#field-lookups-intro|<span class="std std-ref">models and database queries documentation</span>]].
+
有关介绍,请参阅 [[../../../topics/db/queries#field-lookups-intro|模型和数据库查询文档]]
  
Django's built-in lookups are listed below. It is also possible to write
+
下面列出了 Django 的内置查找。 也可以为模型字段编写 [[../../../howto/custom-lookups|自定义查找]]
[[../../../howto/custom-lookups|<span class="doc">custom lookups</span>]] for model fields.
 
  
As a convenience when no lookup type is provided (like in
+
为了方便,当没有提供查找类型时(如 <code>Entry.objects.get(id=14)</code>),查找类型假定为 [[#id11|:lookup:`exact`]]
<code>Entry.objects.get(id=14)</code>) the lookup type is assumed to be [[#std-fieldlookup-exact|<code>exact</code>]].
 
  
 
<div id="exact" class="section">
 
<div id="exact" class="section">
  
<span id="std-fieldlookup-exact"></span><span id="std:fieldlookup-exact"></span>
+
==== exact ====
==== <code>exact</code> ====
 
  
Exact match. If the value provided for comparison is <code>None</code>, it will be
+
完全符合。 如果为比较提供的值是 <code>None</code>,它将被解释为 SQL <code>NULL</code>(有关更多详细信息,请参阅 [[#id13|:lookup:`isnull`]])。
interpreted as an SQL <code>NULL</code> (see [[#std-fieldlookup-isnull|<code>isnull</code>]] for more details).
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,868行: 第3,091行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.get(id__exact=14)
+
<syntaxhighlight lang="python">Entry.objects.get(id__exact=14)
Entry.objects.get(id__exact=None)</pre>
+
Entry.objects.get(id__exact=None)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalents:
+
SQL 等效项:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,880行: 第3,103行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE id = 14;
+
<syntaxhighlight lang="python">SELECT ... WHERE id = 14;
SELECT ... WHERE id IS NULL;</pre>
+
SELECT ... WHERE id IS NULL;</syntaxhighlight>
  
 
</div>
 
</div>
第3,888行: 第3,111行:
 
<div class="admonition-mysql-comparisons admonition">
 
<div class="admonition-mysql-comparisons admonition">
  
MySQL comparisons
+
MySQL 比较
  
In MySQL, a database table's &quot;collation&quot; setting determines whether
+
MySQL 中,数据库表的“排序规则”设置确定 <code>exact</code> 比较是否区分大小写。 这是一个数据库设置, ''不是'' 一个 Django 设置。 可以将 MySQL 表配置为使用区分大小写的比较,但需要进行一些权衡。 有关这方面的更多信息,请参阅 [[../../databases|数据库]] 文档中的 [[../../databases#mysql-collation|整理部分]]
<code>exact</code> comparisons are case-sensitive. This is a database setting, ''not''
 
a Django setting. It's possible to configure your MySQL tables to use
 
case-sensitive comparisons, but some trade-offs are involved. For more
 
information about this, see the [[../../databases#mysql-collation|<span class="std std-ref">collation section</span>]]
 
in the [[../../databases|<span class="doc">databases</span>]] documentation.
 
  
  
第3,903行: 第3,121行:
 
<div id="iexact" class="section">
 
<div id="iexact" class="section">
  
<span id="std-fieldlookup-iexact"></span><span id="std:fieldlookup-iexact"></span>
+
==== iexact ====
==== <code>iexact</code> ====
 
  
Case-insensitive exact match. If the value provided for comparison is <code>None</code>,
+
不区分大小写的精确匹配。 如果为比较提供的值是 <code>None</code>,它将被解释为 SQL <code>NULL</code>(有关更多详细信息,请参阅 [[#id15|:lookup:`isnull`]])。
it will be interpreted as an SQL <code>NULL</code> (see [[#std-fieldlookup-isnull|<code>isnull</code>]] for more
 
details).
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,916行: 第3,131行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Blog.objects.get(name__iexact='beatles blog')
+
<syntaxhighlight lang="python">Blog.objects.get(name__iexact='beatles blog')
Blog.objects.get(name__iexact=None)</pre>
+
Blog.objects.get(name__iexact=None)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalents:
+
SQL 等效项:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,928行: 第3,143行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE name ILIKE 'beatles blog';
+
<syntaxhighlight lang="python">SELECT ... WHERE name ILIKE 'beatles blog';
SELECT ... WHERE name IS NULL;</pre>
+
SELECT ... WHERE name IS NULL;</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Note the first query will match <code>'Beatles Blog'</code>, <code>'beatles blog'</code>,
+
请注意,第一个查询将匹配 <code>'Beatles Blog'</code><code>'beatles blog'</code><code>'BeAtLes BLoG'</code> 等。
<code>'BeAtLes BLoG'</code>, etc.
 
  
 
<div class="admonition-sqlite-users admonition">
 
<div class="admonition-sqlite-users admonition">
  
SQLite users
+
SQLite 用户
  
When using the SQLite backend and non-ASCII strings, bear in mind the
+
使用 SQLite 后端和非 ASCII 字符串时,请记住有关字符串比较的 [[../../databases#sqlite-string-matching|数据库注释]] SQLite 不会对非 ASCII 字符串进行不区分大小写的匹配。
[[../../databases#sqlite-string-matching|<span class="std std-ref">database note</span>]] about string comparisons.
 
SQLite does not do case-insensitive matching for non-ASCII strings.
 
  
  
第3,951行: 第3,163行:
 
<div id="contains" class="section">
 
<div id="contains" class="section">
  
<span id="std-fieldlookup-contains"></span><span id="std:fieldlookup-contains"></span>
+
==== contains ====
==== <code>contains</code> ====
 
  
Case-sensitive containment test.
+
区分大小写的包含测试。
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,962行: 第3,173行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.get(headline__contains='Lennon')</pre>
+
<syntaxhighlight lang="python">Entry.objects.get(headline__contains='Lennon')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalent:
+
SQL 等价于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第3,973行: 第3,184行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE headline LIKE '%Lennon%';</pre>
+
<syntaxhighlight lang="python">SELECT ... WHERE headline LIKE '%Lennon%';</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Note this will match the headline <code>'Lennon honored today'</code> but not <code>'lennon honored today'</code>.
+
请注意,这将匹配标题 <code>'Lennon honored today'</code> 但不匹配 <code>'lennon honored today'</code>
  
 
<div class="admonition-sqlite-users admonition">
 
<div class="admonition-sqlite-users admonition">
  
SQLite users
+
SQLite 用户
  
SQLite doesn't support case-sensitive <code>LIKE</code> statements; <code>contains</code>
+
SQLite 不支持区分大小写的 <code>LIKE</code> 语句; <code>contains</code> 的作用类似于 SQLite 的 <code>icontains</code>。 有关更多信息,请参阅 [[../../databases#sqlite-string-matching|数据库注释]]
acts like <code>icontains</code> for SQLite. See the [[../../databases#sqlite-string-matching|<span class="std std-ref">database note</span>]] for more information.
 
  
  
第3,993行: 第3,203行:
 
<div id="icontains" class="section">
 
<div id="icontains" class="section">
  
<span id="std-fieldlookup-icontains"></span><span id="std:fieldlookup-icontains"></span>
+
==== icontains ====
==== <code>icontains</code> ====
 
  
Case-insensitive containment test.
+
不区分大小写的包含测试。
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,004行: 第3,213行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.get(headline__icontains='Lennon')</pre>
+
<syntaxhighlight lang="python">Entry.objects.get(headline__icontains='Lennon')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalent:
+
SQL 等价于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,015行: 第3,224行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE headline ILIKE '%Lennon%';</pre>
+
<syntaxhighlight lang="python">SELECT ... WHERE headline ILIKE '%Lennon%';</syntaxhighlight>
  
 
</div>
 
</div>
第4,022行: 第3,231行:
 
<div class="admonition-sqlite-users admonition">
 
<div class="admonition-sqlite-users admonition">
  
SQLite users
+
SQLite 用户
  
When using the SQLite backend and non-ASCII strings, bear in mind the
+
使用 SQLite 后端和非 ASCII 字符串时,请记住有关字符串比较的 [[../../databases#sqlite-string-matching|数据库注释]]
[[../../databases#sqlite-string-matching|<span class="std std-ref">database note</span>]] about string comparisons.
 
  
  
第4,033行: 第3,241行:
 
<div id="in" class="section">
 
<div id="in" class="section">
  
<span id="std-fieldlookup-in"></span><span id="std:fieldlookup-in"></span>
+
==== in ====
==== <code>in</code> ====
 
  
In a given iterable; often a list, tuple, or queryset. It's not a common use
+
在给定的迭代中; 通常是列表、元组或查询集。 这不是一个常见的用例,但接受字符串(可迭代)。
case, but strings (being iterables) are accepted.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,045行: 第3,251行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(id__in=[1, 3, 4])
+
<syntaxhighlight lang="python">Entry.objects.filter(id__in=[1, 3, 4])
Entry.objects.filter(headline__in='abc')</pre>
+
Entry.objects.filter(headline__in='abc')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalents:
+
SQL 等效项:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,057行: 第3,263行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE id IN (1, 3, 4);
+
<syntaxhighlight lang="python">SELECT ... WHERE id IN (1, 3, 4);
SELECT ... WHERE headline IN ('a', 'b', 'c');</pre>
+
SELECT ... WHERE headline IN ('a', 'b', 'c');</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
You can also use a queryset to dynamically evaluate the list of values
+
您还可以使用查询集来动态评估值列表,而不是提供文字值列表:
instead of providing a list of literal values:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,070行: 第3,275行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>inner_qs = Blog.objects.filter(name__contains='Cheddar')
+
<syntaxhighlight lang="python">inner_qs = Blog.objects.filter(name__contains='Cheddar')
entries = Entry.objects.filter(blog__in=inner_qs)</pre>
+
entries = Entry.objects.filter(blog__in=inner_qs)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
This queryset will be evaluated as subselect statement:
+
此查询集将作为子选择语句进行评估:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,082行: 第3,287行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE '%Cheddar%')</pre>
+
<syntaxhighlight lang="python">SELECT ... WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE '%Cheddar%')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
If you pass in a <code>QuerySet</code> resulting from <code>values()</code> or <code>values_list()</code>
+
如果您将 <code>values()</code> <code>values_list()</code> 产生的 <code>QuerySet</code> 作为值传递给 <code>__in</code> 查找,则需要确保只提取一个字段结果。 例如,这将起作用(过滤博客名称):
as the value to an <code>__in</code> lookup, you need to ensure you are only extracting
 
one field in the result. For example, this will work (filtering on the blog
 
names):
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,096行: 第3,298行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>inner_qs = Blog.objects.filter(name__contains='Ch').values('name')
+
<syntaxhighlight lang="python">inner_qs = Blog.objects.filter(name__contains='Ch').values('name')
entries = Entry.objects.filter(blog__name__in=inner_qs)</pre>
+
entries = Entry.objects.filter(blog__name__in=inner_qs)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
This example will raise an exception, since the inner query is trying to
+
此示例将引发异常,因为内部查询试图提取两个字段值,其中只需要一个:
extract two field values, where only one is expected:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,109行: 第3,310行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre># Bad code! Will raise a TypeError.
+
<syntaxhighlight lang="python"># Bad code! Will raise a TypeError.
 
inner_qs = Blog.objects.filter(name__contains='Ch').values('name', 'id')
 
inner_qs = Blog.objects.filter(name__contains='Ch').values('name', 'id')
entries = Entry.objects.filter(blog__name__in=inner_qs)</pre>
+
entries = Entry.objects.filter(blog__name__in=inner_qs)</syntaxhighlight>
  
 
</div>
 
</div>
第4,118行: 第3,319行:
 
<div id="nested-queries-performance" class="admonition-performance-considerations admonition">
 
<div id="nested-queries-performance" class="admonition-performance-considerations admonition">
  
性能考虑因素
+
性能注意事项
  
Be cautious about using nested queries and understand your database
+
谨慎使用嵌套查询并了解您的数据库服务器的性能特征(如果有疑问,请进行基准测试!)。 一些数据库后端,尤其是 MySQL,不能很好地优化嵌套查询。 在这些情况下,提取值列表然后将其传递到第二个查询中会更有效。 也就是说,执行两个查询而不是一个:
server's performance characteristics (if in doubt, benchmark!). Some
 
database backends, most notably MySQL, don't optimize nested queries very
 
well. It is more efficient, in those cases, to extract a list of values
 
and then pass that into the second query. That is, execute two queries
 
instead of one:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,131行: 第3,327行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>values = Blog.objects.filter(
+
<syntaxhighlight lang="python">values = Blog.objects.filter(
 
         name__contains='Cheddar').values_list('pk', flat=True)
 
         name__contains='Cheddar').values_list('pk', flat=True)
entries = Entry.objects.filter(blog__in=list(values))</pre>
+
entries = Entry.objects.filter(blog__in=list(values))</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Note the <code>list()</code> call around the Blog <code>QuerySet</code> to force execution of
+
请注意博客 <code>QuerySet</code> 周围的 <code>list()</code> 调用以强制执行第一个查询。 没有它,将执行嵌套查询,因为 [[../../../topics/db/queries#querysets-are-lazy|QuerySets 是惰性的]]
the first query. Without it, a nested query would be executed, because
 
[[../../../topics/db/queries#querysets-are-lazy|<span class="std std-ref">QuerySet 是惰性的</span>]].
 
  
  
第4,148行: 第3,342行:
 
<div id="gt" class="section">
 
<div id="gt" class="section">
  
<span id="std-fieldlookup-gt"></span><span id="std:fieldlookup-gt"></span>
+
==== gt ====
==== <code>gt</code> ====
 
  
Greater than.
+
大于。
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,159行: 第3,352行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(id__gt=4)</pre>
+
<syntaxhighlight lang="python">Entry.objects.filter(id__gt=4)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalent:
+
SQL 等价于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,170行: 第3,363行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE id &gt; 4;</pre>
+
<syntaxhighlight lang="python">SELECT ... WHERE id > 4;</syntaxhighlight>
  
 
</div>
 
</div>
第4,179行: 第3,372行:
 
<div id="gte" class="section">
 
<div id="gte" class="section">
  
<span id="std-fieldlookup-gte"></span><span id="std:fieldlookup-gte"></span>
+
==== gte ====
==== <code>gte</code> ====
 
  
Greater than or equal to.
+
大于等于。
  
  
第4,188行: 第3,380行:
 
<div id="lt" class="section">
 
<div id="lt" class="section">
  
<span id="std-fieldlookup-lt"></span><span id="std:fieldlookup-lt"></span>
+
==== lt ====
==== <code>lt</code> ====
 
  
Less than.
+
小于。
  
  
第4,197行: 第3,388行:
 
<div id="lte" class="section">
 
<div id="lte" class="section">
  
<span id="std-fieldlookup-lte"></span><span id="std:fieldlookup-lte"></span>
+
==== lte ====
==== <code>lte</code> ====
 
  
Less than or equal to.
+
小于等于
  
  
第4,206行: 第3,396行:
 
<div id="startswith" class="section">
 
<div id="startswith" class="section">
  
<span id="std-fieldlookup-startswith"></span><span id="std:fieldlookup-startswith"></span>
+
==== startswith ====
==== <code>startswith</code> ====
 
  
Case-sensitive starts-with.
+
区分大小写的开头为。
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,217行: 第3,406行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(headline__startswith='Lennon')</pre>
+
<syntaxhighlight lang="python">Entry.objects.filter(headline__startswith='Lennon')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalent:
+
SQL 等价于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,228行: 第3,417行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE headline LIKE 'Lennon%';</pre>
+
<syntaxhighlight lang="python">SELECT ... WHERE headline LIKE 'Lennon%';</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQLite doesn't support case-sensitive <code>LIKE</code> statements; <code>startswith</code> acts
+
SQLite 不支持区分大小写的 <code>LIKE</code> 语句; <code>startswith</code> 的作用类似于 SQLite 的 <code>istartswith</code>
like <code>istartswith</code> for SQLite.
 
  
  
第4,240行: 第3,428行:
 
<div id="istartswith" class="section">
 
<div id="istartswith" class="section">
  
<span id="std-fieldlookup-istartswith"></span><span id="std:fieldlookup-istartswith"></span>
+
==== istartswith ====
==== <code>istartswith</code> ====
 
  
Case-insensitive starts-with.
+
不区分大小写的开头为。
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,251行: 第3,438行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(headline__istartswith='Lennon')</pre>
+
<syntaxhighlight lang="python">Entry.objects.filter(headline__istartswith='Lennon')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalent:
+
SQL 等价于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,262行: 第3,449行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE headline ILIKE 'Lennon%';</pre>
+
<syntaxhighlight lang="python">SELECT ... WHERE headline ILIKE 'Lennon%';</syntaxhighlight>
  
 
</div>
 
</div>
第4,269行: 第3,456行:
 
<div class="admonition-sqlite-users admonition">
 
<div class="admonition-sqlite-users admonition">
  
SQLite users
+
SQLite 用户
  
When using the SQLite backend and non-ASCII strings, bear in mind the
+
使用 SQLite 后端和非 ASCII 字符串时,请记住有关字符串比较的 [[../../databases#sqlite-string-matching|数据库注释]]
[[../../databases#sqlite-string-matching|<span class="std std-ref">database note</span>]] about string comparisons.
 
  
  
第4,280行: 第3,466行:
 
<div id="endswith" class="section">
 
<div id="endswith" class="section">
  
<span id="std-fieldlookup-endswith"></span><span id="std:fieldlookup-endswith"></span>
+
==== endswith ====
==== <code>endswith</code> ====
 
  
Case-sensitive ends-with.
+
区分大小写的结尾为。
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,291行: 第3,476行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(headline__endswith='Lennon')</pre>
+
<syntaxhighlight lang="python">Entry.objects.filter(headline__endswith='Lennon')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalent:
+
SQL 等价于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,302行: 第3,487行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE headline LIKE '%Lennon';</pre>
+
<syntaxhighlight lang="python">SELECT ... WHERE headline LIKE '%Lennon';</syntaxhighlight>
  
 
</div>
 
</div>
第4,309行: 第3,494行:
 
<div class="admonition-sqlite-users admonition">
 
<div class="admonition-sqlite-users admonition">
  
SQLite users
+
SQLite 用户
  
SQLite doesn't support case-sensitive <code>LIKE</code> statements; <code>endswith</code>
+
SQLite 不支持区分大小写的 <code>LIKE</code> 语句; <code>endswith</code> 的作用类似于 SQLite 的 <code>iendswith</code>。 有关更多信息,请参阅 [[../../databases#sqlite-string-matching|数据库注释]] 文档。
acts like <code>iendswith</code> for SQLite. Refer to the [[../../databases#sqlite-string-matching|<span class="std std-ref">database note</span>]] documentation for more.
 
  
  
第4,320行: 第3,504行:
 
<div id="iendswith" class="section">
 
<div id="iendswith" class="section">
  
<span id="std-fieldlookup-iendswith"></span><span id="std:fieldlookup-iendswith"></span>
+
==== iendswith ====
==== <code>iendswith</code> ====
 
  
Case-insensitive ends-with.
+
不区分大小写的结尾为。
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,331行: 第3,514行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(headline__iendswith='Lennon')</pre>
+
<syntaxhighlight lang="python">Entry.objects.filter(headline__iendswith='Lennon')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalent:
+
SQL 等价于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,342行: 第3,525行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE headline ILIKE '%Lennon'</pre>
+
<syntaxhighlight lang="python">SELECT ... WHERE headline ILIKE '%Lennon'</syntaxhighlight>
  
 
</div>
 
</div>
第4,349行: 第3,532行:
 
<div class="admonition-sqlite-users admonition">
 
<div class="admonition-sqlite-users admonition">
  
SQLite users
+
SQLite 用户
  
When using the SQLite backend and non-ASCII strings, bear in mind the
+
使用 SQLite 后端和非 ASCII 字符串时,请记住有关字符串比较的 [[../../databases#sqlite-string-matching|数据库注释]]
[[../../databases#sqlite-string-matching|<span class="std std-ref">database note</span>]] about string comparisons.
 
  
  
第4,360行: 第3,542行:
 
<div id="range" class="section">
 
<div id="range" class="section">
  
<span id="std-fieldlookup-range"></span><span id="std:fieldlookup-range"></span>
+
==== range ====
==== <code>range</code> ====
 
  
Range test (inclusive).
+
范围测试(含)。
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,371行: 第3,552行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>import datetime
+
<syntaxhighlight lang="python">import datetime
 
start_date = datetime.date(2005, 1, 1)
 
start_date = datetime.date(2005, 1, 1)
 
end_date = datetime.date(2005, 3, 31)
 
end_date = datetime.date(2005, 3, 31)
Entry.objects.filter(pub_date__range=(start_date, end_date))</pre>
+
Entry.objects.filter(pub_date__range=(start_date, end_date))</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalent:
+
SQL 等价于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,385行: 第3,566行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31';</pre>
+
<syntaxhighlight lang="python">SELECT ... WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31';</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
You can use <code>range</code> anywhere you can use <code>BETWEEN</code> in SQL for dates,
+
在 SQL 中可以使用 <code>BETWEEN</code> 的任何地方都可以使用 <code>range</code> — 用于日期、数字甚至字符。
numbers and even characters.
 
  
 
<div class="admonition warning">
 
<div class="admonition warning">
第4,397行: 第3,577行:
 
警告
 
警告
  
Filtering a <code>DateTimeField</code> with dates won't include items on the last
+
用日期过滤 <code>DateTimeField</code> 将不包括最后一天的项目,因为边界被解释为“给定日期的上午 0 点”。 如果 <code>pub_date</code> 是一个 <code>DateTimeField</code>,上面的表达式会变成这个 SQL:
day, because the bounds are interpreted as &quot;0am on the given date&quot;. If
 
<code>pub_date</code> was a <code>DateTimeField</code>, the above expression would be turned
 
into this SQL:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,406行: 第3,583行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE pub_date BETWEEN '2005-01-01 00:00:00' and '2005-03-31 00:00:00';</pre>
+
<syntaxhighlight lang="python">SELECT ... WHERE pub_date BETWEEN '2005-01-01 00:00:00' and '2005-03-31 00:00:00';</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Generally speaking, you can't mix dates and datetimes.
+
一般来说,您不能混合日期和日期时间。
  
  
第4,419行: 第3,596行:
 
<div id="date" class="section">
 
<div id="date" class="section">
  
<span id="std-fieldlookup-date"></span><span id="std:fieldlookup-date"></span>
+
==== date ====
==== <code>date</code> ====
 
  
For datetime fields, casts the value as date. Allows chaining additional field
+
对于日期时间字段,将值转换为日期。 允许链接额外的字段查找。 获取日期值。
lookups. Takes a date value.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,431行: 第3,606行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
+
<syntaxhighlight lang="python">Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))</pre>
+
Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
(No equivalent SQL code fragment is included for this lookup because
+
(由于不同的数据库引擎对相关查询的实现各不相同,因此本次查询不包含等效的 SQL 代码片段)。
implementation of the relevant query varies among different database engines.)
 
  
When [[../../settings#std-setting-USE_TZ|<code>USE_TZ</code>]] is <code>True</code>, fields are converted to the current time
+
[[#id17|:setting:`USE_TZ`]] <code>True</code> 时,字段在过滤前转换为当前时区。 这需要数据库 [[#database-time-zone-definitions|中的]] 时区定义。
zone before filtering. This requires [[#database-time-zone-definitions|<span class="std std-ref">time zone definitions in the
 
database</span>]].
 
  
  
第4,448行: 第3,620行:
 
<div id="year" class="section">
 
<div id="year" class="section">
  
<span id="std-fieldlookup-year"></span><span id="std:fieldlookup-year"></span>
+
==== year ====
==== <code>year</code> ====
 
  
For date and datetime fields, an exact year match. Allows chaining additional
+
对于日期和日期时间字段,精确的年份匹配。 允许链接额外的字段查找。 取整数年。
field lookups. Takes an integer year.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,460行: 第3,630行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(pub_date__year=2005)
+
<syntaxhighlight lang="python">Entry.objects.filter(pub_date__year=2005)
Entry.objects.filter(pub_date__year__gte=2005)</pre>
+
Entry.objects.filter(pub_date__year__gte=2005)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalent:
+
SQL 等价于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,472行: 第3,642行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31';
+
<syntaxhighlight lang="python">SELECT ... WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31';
SELECT ... WHERE pub_date &gt;= '2005-01-01';</pre>
+
SELECT ... WHERE pub_date >= '2005-01-01';</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
(The exact SQL syntax varies for each database engine.)
+
(确切的 SQL 语法因每个数据库引擎而异)。
  
When [[../../settings#std-setting-USE_TZ|<code>USE_TZ</code>]] is <code>True</code>, datetime fields are converted to the
+
[[#id19|:setting:`USE_TZ`]] <code>True</code> 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 [[#database-time-zone-definitions|中的]] 时区定义。
current time zone before filtering. This requires [[#database-time-zone-definitions|<span class="std std-ref">time zone definitions
 
in the database</span>]].
 
  
  
第4,488行: 第3,656行:
 
<div id="iso-year" class="section">
 
<div id="iso-year" class="section">
  
<span id="std-fieldlookup-iso_year"></span><span id="std:fieldlookup-iso_year"></span>
+
==== iso_year ====
==== <code>iso_year</code> ====
 
  
 
<div class="versionadded">
 
<div class="versionadded">
  
 +
<span class="versionmodified added">2.2 版中的新功能。</span>
  
  
 
</div>
 
</div>
For date and datetime fields, an exact ISO 8601 week-numbering year match.
+
对于日期和日期时间字段,精确的 ISO 8601 周编号年份匹配。 允许链接额外的字段查找。 取整数年。
Allows chaining additional field lookups. Takes an integer year.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,505行: 第3,672行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(pub_date__iso_year=2005)
+
<syntaxhighlight lang="python">Entry.objects.filter(pub_date__iso_year=2005)
Entry.objects.filter(pub_date__iso_year__gte=2005)</pre>
+
Entry.objects.filter(pub_date__iso_year__gte=2005)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
(The exact SQL syntax varies for each database engine.)
+
(确切的 SQL 语法因每个数据库引擎而异)。
  
When [[../../settings#std-setting-USE_TZ|<code>USE_TZ</code>]] is <code>True</code>, datetime fields are converted to the
+
[[#id21|:setting:`USE_TZ`]] <code>True</code> 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 [[#database-time-zone-definitions|中的]] 时区定义。
current time zone before filtering. This requires [[#database-time-zone-definitions|<span class="std std-ref">time zone definitions
 
in the database</span>]].
 
  
  
第4,521行: 第3,686行:
 
<div id="month" class="section">
 
<div id="month" class="section">
  
<span id="std-fieldlookup-month"></span><span id="std:fieldlookup-month"></span>
+
==== month ====
==== <code>month</code> ====
 
  
For date and datetime fields, an exact month match. Allows chaining additional
+
对于日期和日期时间字段,精确的月份匹配。 允许链接额外的字段查找。 取整数 1(一月)到 12(十二月)。
field lookups. Takes an integer 1 (January) through 12 (December).
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,533行: 第3,696行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(pub_date__month=12)
+
<syntaxhighlight lang="python">Entry.objects.filter(pub_date__month=12)
Entry.objects.filter(pub_date__month__gte=6)</pre>
+
Entry.objects.filter(pub_date__month__gte=6)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalent:
+
SQL 等价于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,545行: 第3,708行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE EXTRACT('month' FROM pub_date) = '12';
+
<syntaxhighlight lang="python">SELECT ... WHERE EXTRACT('month' FROM pub_date) = '12';
SELECT ... WHERE EXTRACT('month' FROM pub_date) &gt;= '6';</pre>
+
SELECT ... WHERE EXTRACT('month' FROM pub_date) >= '6';</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
(The exact SQL syntax varies for each database engine.)
+
(确切的 SQL 语法因每个数据库引擎而异)。
  
When [[../../settings#std-setting-USE_TZ|<code>USE_TZ</code>]] is <code>True</code>, datetime fields are converted to the
+
[[#id23|:setting:`USE_TZ`]] <code>True</code> 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 [[#database-time-zone-definitions|中的]] 时区定义。
current time zone before filtering. This requires [[#database-time-zone-definitions|<span class="std std-ref">time zone definitions
 
in the database</span>]].
 
  
  
第4,561行: 第3,722行:
 
<div id="day" class="section">
 
<div id="day" class="section">
  
<span id="std-fieldlookup-day"></span><span id="std:fieldlookup-day"></span>
+
==== day ====
==== <code>day</code> ====
 
  
For date and datetime fields, an exact day match. Allows chaining additional
+
对于日期和日期时间字段,精确的日期匹配。 允许链接额外的字段查找。 需要整数天。
field lookups. Takes an integer day.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,573行: 第3,732行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(pub_date__day=3)
+
<syntaxhighlight lang="python">Entry.objects.filter(pub_date__day=3)
Entry.objects.filter(pub_date__day__gte=3)</pre>
+
Entry.objects.filter(pub_date__day__gte=3)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalent:
+
SQL 等价于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,585行: 第3,744行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE EXTRACT('day' FROM pub_date) = '3';
+
<syntaxhighlight lang="python">SELECT ... WHERE EXTRACT('day' FROM pub_date) = '3';
SELECT ... WHERE EXTRACT('day' FROM pub_date) &gt;= '3';</pre>
+
SELECT ... WHERE EXTRACT('day' FROM pub_date) >= '3';</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
(The exact SQL syntax varies for each database engine.)
+
(确切的 SQL 语法因每个数据库引擎而异)。
  
Note this will match any record with a pub_date on the third day of the month,
+
请注意,这将匹配任何带有 pub_date 的月份第三天的记录,如 1 月 3 日,7 月 3 日等。
such as January 3, July 3, etc.
 
  
When [[../../settings#std-setting-USE_TZ|<code>USE_TZ</code>]] is <code>True</code>, datetime fields are converted to the
+
[[#id25|:setting:`USE_TZ`]] <code>True</code> 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 [[#database-time-zone-definitions|中的]] 时区定义。
current time zone before filtering. This requires [[#database-time-zone-definitions|<span class="std std-ref">time zone definitions
 
in the database</span>]].
 
  
  
第4,604行: 第3,760行:
 
<div id="week" class="section">
 
<div id="week" class="section">
  
<span id="std-fieldlookup-week"></span><span id="std:fieldlookup-week"></span>
+
==== week ====
==== <code>week</code> ====
 
  
For date and datetime fields, return the week number (1-52 or 53) according
+
对于日期和日期时间字段,根据 [https://en.wikipedia.org/wiki/ISO-8601 ISO-8601] 返回周数(1-52 或 53),即周从星期一开始,第一周包含年度的第一个星期四。
to [https://en.wikipedia.org/wiki/ISO-8601 ISO-8601], i.e., weeks start
 
on a Monday and the first week contains the year's first Thursday.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,617行: 第3,770行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(pub_date__week=52)
+
<syntaxhighlight lang="python">Entry.objects.filter(pub_date__week=52)
Entry.objects.filter(pub_date__week__gte=32, pub_date__week__lte=38)</pre>
+
Entry.objects.filter(pub_date__week__gte=32, pub_date__week__lte=38)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
(No equivalent SQL code fragment is included for this lookup because
+
(由于不同的数据库引擎对相关查询的实现各不相同,因此本次查询不包含等效的 SQL 代码片段)。
implementation of the relevant query varies among different database engines.)
 
  
When [[../../settings#std-setting-USE_TZ|<code>USE_TZ</code>]] is <code>True</code>, datetime fields are converted to the
+
[[#id27|:setting:`USE_TZ`]] <code>True</code> 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 [[#database-time-zone-definitions|中的]] 时区定义。
current time zone before filtering. This requires [[#database-time-zone-definitions|<span class="std std-ref">time zone definitions
 
in the database</span>]].
 
  
  
第4,634行: 第3,784行:
 
<div id="week-day" class="section">
 
<div id="week-day" class="section">
  
<span id="std-fieldlookup-week_day"></span><span id="std:fieldlookup-week_day"></span>
+
==== week_day ====
==== <code>week_day</code> ====
 
  
For date and datetime fields, a 'day of the week' match. Allows chaining
+
对于日期和日期时间字段,“星期几”匹配。 允许链接额外的字段查找。
additional field lookups.
 
  
Takes an integer value representing the day of week from 1 (Sunday) to 7
+
从 1(星期日)到 7(星期六)取一个整数值,代表一周的一天。
(Saturday).
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,649行: 第3,796行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(pub_date__week_day=2)
+
<syntaxhighlight lang="python">Entry.objects.filter(pub_date__week_day=2)
Entry.objects.filter(pub_date__week_day__gte=2)</pre>
+
Entry.objects.filter(pub_date__week_day__gte=2)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
(No equivalent SQL code fragment is included for this lookup because
+
(由于不同的数据库引擎对相关查询的实现各不相同,因此本次查询不包含等效的 SQL 代码片段)。
implementation of the relevant query varies among different database engines.)
 
  
Note this will match any record with a <code>pub_date</code> that falls on a Monday (day
+
请注意,这将匹配任何具有 <code>pub_date</code> 位于星期一(一周的第 2 天)的记录,而不管它发生在哪个月份或年份。 工作日被索引,第 1 天是星期日,第 7 天是星期六。
2 of the week), regardless of the month or year in which it occurs. Week days
 
are indexed with day 1 being Sunday and day 7 being Saturday.
 
  
When [[../../settings#std-setting-USE_TZ|<code>USE_TZ</code>]] is <code>True</code>, datetime fields are converted to the
+
[[#id29|:setting:`USE_TZ`]] <code>True</code> 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 [[#database-time-zone-definitions|中的]] 时区定义。
current time zone before filtering. This requires [[#database-time-zone-definitions|<span class="std std-ref">time zone definitions
 
in the database</span>]].
 
  
  
第4,670行: 第3,812行:
 
<div id="quarter" class="section">
 
<div id="quarter" class="section">
  
<span id="std-fieldlookup-quarter"></span><span id="std:fieldlookup-quarter"></span>
+
==== quarter ====
==== <code>quarter</code> ====
 
  
For date and datetime fields, a 'quarter of the year' match. Allows chaining
+
对于日期和日期时间字段,“一年中的一个季度”匹配。 允许链接额外的字段查找。 取一个 1 4 之间的整数值,表示一年中的一个季度。
additional field lookups. Takes an integer value between 1 and 4 representing
 
the quarter of the year.
 
  
Example to retrieve entries in the second quarter (April 1 to June 30):
+
检索第二季度(4 月 1 日至 6 月 30 日)条目的示例:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,683行: 第3,822行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(pub_date__quarter=2)</pre>
+
<syntaxhighlight lang="python">Entry.objects.filter(pub_date__quarter=2)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
(No equivalent SQL code fragment is included for this lookup because
+
(由于不同的数据库引擎对相关查询的实现各不相同,因此本次查询不包含等效的 SQL 代码片段)。
implementation of the relevant query varies among different database engines.)
 
  
When [[../../settings#std-setting-USE_TZ|<code>USE_TZ</code>]] is <code>True</code>, datetime fields are converted to the
+
[[#id31|:setting:`USE_TZ`]] <code>True</code> 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 [[#database-time-zone-definitions|中的]] 时区定义。
current time zone before filtering. This requires [[#database-time-zone-definitions|<span class="std std-ref">time zone definitions
 
in the database</span>]].
 
  
  
第4,699行: 第3,835行:
 
<div id="time" class="section">
 
<div id="time" class="section">
  
<span id="std-fieldlookup-time"></span><span id="std:fieldlookup-time"></span>
+
==== time ====
==== <code>time</code> ====
 
  
For datetime fields, casts the value as time. Allows chaining additional field
+
对于日期时间字段,将值转换为时间。 允许链接额外的字段查找。 采用 <code>datetime.time</code> 值。
lookups. Takes a <code>datetime.time</code> value.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,711行: 第3,845行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(pub_date__time=datetime.time(14, 30))
+
<syntaxhighlight lang="python">Entry.objects.filter(pub_date__time=datetime.time(14, 30))
Entry.objects.filter(pub_date__time__range=(datetime.time(8), datetime.time(17)))</pre>
+
Entry.objects.filter(pub_date__time__range=(datetime.time(8), datetime.time(17)))</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
(No equivalent SQL code fragment is included for this lookup because
+
(由于不同的数据库引擎对相关查询的实现各不相同,因此本次查询不包含等效的 SQL 代码片段)。
implementation of the relevant query varies among different database engines.)
 
  
When [[../../settings#std-setting-USE_TZ|<code>USE_TZ</code>]] is <code>True</code>, fields are converted to the current time
+
[[#id33|:setting:`USE_TZ`]] <code>True</code> 时,字段在过滤前转换为当前时区。 这需要数据库 [[#database-time-zone-definitions|中的]] 时区定义。
zone before filtering. This requires [[#database-time-zone-definitions|<span class="std std-ref">time zone definitions in the
 
database</span>]].
 
  
  
第4,728行: 第3,859行:
 
<div id="hour" class="section">
 
<div id="hour" class="section">
  
<span id="std-fieldlookup-hour"></span><span id="std:fieldlookup-hour"></span>
+
==== hour ====
==== <code>hour</code> ====
 
  
For datetime and time fields, an exact hour match. Allows chaining additional
+
对于日期时间和时间字段,精确的小时匹配。 允许链接额外的字段查找。 取 0 23 之间的整数。
field lookups. Takes an integer between 0 and 23.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,740行: 第3,869行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Event.objects.filter(timestamp__hour=23)
+
<syntaxhighlight lang="python">Event.objects.filter(timestamp__hour=23)
 
Event.objects.filter(time__hour=5)
 
Event.objects.filter(time__hour=5)
Event.objects.filter(timestamp__hour__gte=12)</pre>
+
Event.objects.filter(timestamp__hour__gte=12)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalent:
+
SQL 等价于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,753行: 第3,882行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE EXTRACT('hour' FROM timestamp) = '23';
+
<syntaxhighlight lang="python">SELECT ... WHERE EXTRACT('hour' FROM timestamp) = '23';
 
SELECT ... WHERE EXTRACT('hour' FROM time) = '5';
 
SELECT ... WHERE EXTRACT('hour' FROM time) = '5';
SELECT ... WHERE EXTRACT('hour' FROM timestamp) &gt;= '12';</pre>
+
SELECT ... WHERE EXTRACT('hour' FROM timestamp) >= '12';</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
(The exact SQL syntax varies for each database engine.)
+
(确切的 SQL 语法因每个数据库引擎而异)。
  
When [[../../settings#std-setting-USE_TZ|<code>USE_TZ</code>]] is <code>True</code>, datetime fields are converted to the
+
[[#id35|:setting:`USE_TZ`]] <code>True</code> 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 [[#database-time-zone-definitions|中的]] 时区定义。
current time zone before filtering. This requires [[#database-time-zone-definitions|<span class="std std-ref">time zone definitions
 
in the database</span>]].
 
  
  
第4,770行: 第3,897行:
 
<div id="minute" class="section">
 
<div id="minute" class="section">
  
<span id="std-fieldlookup-minute"></span><span id="std:fieldlookup-minute"></span>
+
==== minute ====
==== <code>minute</code> ====
 
  
For datetime and time fields, an exact minute match. Allows chaining additional
+
对于日期时间和时间字段,精确的分钟匹配。 允许链接额外的字段查找。 取 0 59 之间的整数。
field lookups. Takes an integer between 0 and 59.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,782行: 第3,907行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Event.objects.filter(timestamp__minute=29)
+
<syntaxhighlight lang="python">Event.objects.filter(timestamp__minute=29)
 
Event.objects.filter(time__minute=46)
 
Event.objects.filter(time__minute=46)
Event.objects.filter(timestamp__minute__gte=29)</pre>
+
Event.objects.filter(timestamp__minute__gte=29)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalent:
+
SQL 等价于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,795行: 第3,920行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE EXTRACT('minute' FROM timestamp) = '29';
+
<syntaxhighlight lang="python">SELECT ... WHERE EXTRACT('minute' FROM timestamp) = '29';
 
SELECT ... WHERE EXTRACT('minute' FROM time) = '46';
 
SELECT ... WHERE EXTRACT('minute' FROM time) = '46';
SELECT ... WHERE EXTRACT('minute' FROM timestamp) &gt;= '29';</pre>
+
SELECT ... WHERE EXTRACT('minute' FROM timestamp) >= '29';</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
(The exact SQL syntax varies for each database engine.)
+
(确切的 SQL 语法因每个数据库引擎而异)。
  
When [[../../settings#std-setting-USE_TZ|<code>USE_TZ</code>]] is <code>True</code>, datetime fields are converted to the
+
[[#id37|:setting:`USE_TZ`]] <code>True</code> 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 [[#database-time-zone-definitions|中的]] 时区定义。
current time zone before filtering. This requires [[#database-time-zone-definitions|<span class="std std-ref">time zone definitions
 
in the database</span>]].
 
  
  
第4,812行: 第3,935行:
 
<div id="second" class="section">
 
<div id="second" class="section">
  
<span id="std-fieldlookup-second"></span><span id="std:fieldlookup-second"></span>
+
==== second ====
==== <code>second</code> ====
 
  
For datetime and time fields, an exact second match. Allows chaining additional
+
对于日期时间和时间字段,精确的第二个匹配。 允许链接额外的字段查找。 取 0 59 之间的整数。
field lookups. Takes an integer between 0 and 59.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,824行: 第3,945行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Event.objects.filter(timestamp__second=31)
+
<syntaxhighlight lang="python">Event.objects.filter(timestamp__second=31)
 
Event.objects.filter(time__second=2)
 
Event.objects.filter(time__second=2)
Event.objects.filter(timestamp__second__gte=31)</pre>
+
Event.objects.filter(timestamp__second__gte=31)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalent:
+
SQL 等价于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,837行: 第3,958行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE EXTRACT('second' FROM timestamp) = '31';
+
<syntaxhighlight lang="python">SELECT ... WHERE EXTRACT('second' FROM timestamp) = '31';
 
SELECT ... WHERE EXTRACT('second' FROM time) = '2';
 
SELECT ... WHERE EXTRACT('second' FROM time) = '2';
SELECT ... WHERE EXTRACT('second' FROM timestamp) &gt;= '31';</pre>
+
SELECT ... WHERE EXTRACT('second' FROM timestamp) >= '31';</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
(The exact SQL syntax varies for each database engine.)
+
(确切的 SQL 语法因每个数据库引擎而异)。
  
When [[../../settings#std-setting-USE_TZ|<code>USE_TZ</code>]] is <code>True</code>, datetime fields are converted to the
+
[[#id39|:setting:`USE_TZ`]] <code>True</code> 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 [[#database-time-zone-definitions|中的]] 时区定义。
current time zone before filtering. This requires [[#database-time-zone-definitions|<span class="std std-ref">time zone definitions
 
in the database</span>]].
 
  
  
第4,854行: 第3,973行:
 
<div id="isnull" class="section">
 
<div id="isnull" class="section">
  
<span id="std-fieldlookup-isnull"></span><span id="std:fieldlookup-isnull"></span>
+
==== isnull ====
==== <code>isnull</code> ====
 
  
Takes either <code>True</code> or <code>False</code>, which correspond to SQL queries of
+
采用 <code>True</code> <code>False</code>,分别对应于 <code>IS NULL</code> <code>IS NOT NULL</code> 的 SQL 查询。
<code>IS NULL</code> and <code>IS NOT NULL</code>, respectively.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,866行: 第3,983行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.filter(pub_date__isnull=True)</pre>
+
<syntaxhighlight lang="python">Entry.objects.filter(pub_date__isnull=True)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalent:
+
SQL 等价于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,877行: 第3,994行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE pub_date IS NULL;</pre>
+
<syntaxhighlight lang="python">SELECT ... WHERE pub_date IS NULL;</syntaxhighlight>
  
 
</div>
 
</div>
第4,886行: 第4,003行:
 
<div id="regex" class="section">
 
<div id="regex" class="section">
  
<span id="std-fieldlookup-regex"></span><span id="std:fieldlookup-regex"></span>
+
==== regex ====
==== <code>regex</code> ====
 
  
Case-sensitive regular expression match.
+
区分大小写的正则表达式匹配。
  
The regular expression syntax is that of the database backend in use.
+
正则表达式语法是正在使用的数据库后端的语法。 对于没有内置正则表达式支持的 SQLite,此功能由(Python)用户定义的 REGEXP 函数提供,因此正则表达式语法是 Python <code>re</code> 模块的语法。
In the case of SQLite, which has no built in regular expression support,
 
this feature is provided by a (Python) user-defined REGEXP function, and
 
the regular expression syntax is therefore that of Python's <code>re</code> module.
 
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,902行: 第4,015行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.get(title__regex=r'^(An?|The) +')</pre>
+
<syntaxhighlight lang="python">Entry.objects.get(title__regex=r'^(An?|The) +')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalents:
+
SQL 等效项:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,913行: 第4,026行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL
+
<syntaxhighlight lang="python">SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL
  
 
SELECT ... WHERE REGEXP_LIKE(title, '^(An?|The) +', 'c'); -- Oracle
 
SELECT ... WHERE REGEXP_LIKE(title, '^(An?|The) +', 'c'); -- Oracle
第4,919行: 第4,032行:
 
SELECT ... WHERE title ~ '^(An?|The) +'; -- PostgreSQL
 
SELECT ... WHERE title ~ '^(An?|The) +'; -- PostgreSQL
  
SELECT ... WHERE title REGEXP '^(An?|The) +'; -- SQLite</pre>
+
SELECT ... WHERE title REGEXP '^(An?|The) +'; -- SQLite</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Using raw strings (e.g., <code>r'foo'</code> instead of <code>'foo'</code>) for passing in the
+
建议使用原始字符串(例如,<code>r'foo'</code> 而不是 <code>'foo'</code>)来传递正则表达式语法。
regular expression syntax is recommended.
 
  
  
第4,931行: 第4,043行:
 
<div id="iregex" class="section">
 
<div id="iregex" class="section">
  
<span id="std-fieldlookup-iregex"></span><span id="std:fieldlookup-iregex"></span>
+
==== iregex ====
==== <code>iregex</code> ====
 
  
Case-insensitive regular expression match.
+
不区分大小写的正则表达式匹配。
  
举例:
+
例子:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,942行: 第4,053行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>Entry.objects.get(title__iregex=r'^(an?|the) +')</pre>
+
<syntaxhighlight lang="python">Entry.objects.get(title__iregex=r'^(an?|the) +')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
SQL equivalents:
+
SQL 等效项:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第4,953行: 第4,064行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>SELECT ... WHERE title REGEXP '^(an?|the) +'; -- MySQL
+
<syntaxhighlight lang="python">SELECT ... WHERE title REGEXP '^(an?|the) +'; -- MySQL
  
 
SELECT ... WHERE REGEXP_LIKE(title, '^(an?|the) +', 'i'); -- Oracle
 
SELECT ... WHERE REGEXP_LIKE(title, '^(an?|the) +', 'i'); -- Oracle
第4,959行: 第4,070行:
 
SELECT ... WHERE title ~* '^(an?|the) +'; -- PostgreSQL
 
SELECT ... WHERE title ~* '^(an?|the) +'; -- PostgreSQL
  
SELECT ... WHERE title REGEXP '(?i)^(an?|the) +'; -- SQLite</pre>
+
SELECT ... WHERE title REGEXP '(?i)^(an?|the) +'; -- SQLite</syntaxhighlight>
  
 
</div>
 
</div>
第4,970行: 第4,081行:
 
<div id="aggregation-functions" class="section">
 
<div id="aggregation-functions" class="section">
  
<span id="id5"></span>
+
<span id="id41"></span>
=== Aggregation functions ===
+
=== 聚合函数 ===
  
Django provides the following aggregation functions in the
+
Django <code>django.db.models</code> 模块中提供了以下聚合函数。 有关如何使用这些聚合函数的详细信息,请参阅 [[../../../topics/db/aggregation|聚合主题指南]] 。 请参阅 [[../expressions#django.db.models|Aggregate]] 文档以了解如何创建聚合。
<code>django.db.models</code> module. For details on how to use these
 
aggregate functions, see [[../../../topics/db/aggregation|<span class="doc">the topic guide on aggregation</span>]]. See the [[../expressions#django.db.models|<code>Aggregate</code>]]
 
documentation to learn how to create your aggregates.
 
  
 
<div class="admonition warning">
 
<div class="admonition warning">
第4,982行: 第4,090行:
 
警告
 
警告
  
SQLite can't handle aggregation on date/time fields out of the box.
+
SQLite 无法处理开箱即用的日期/时间字段的聚合。 这是因为 SQLite 中没有原生日期/时间字段,而 Django 目前使用文本字段模拟这些功能。 尝试在 SQLite 中的日期/时间字段上使用聚合将引发 <code>NotImplementedError</code>
This is because there are no native date/time fields in SQLite and Django
 
currently emulates these features using a text field. Attempts to use
 
aggregation on date/time fields in SQLite will raise
 
<code>NotImplementedError</code>.
 
  
  
第4,992行: 第4,096行:
 
<div class="admonition-note admonition">
 
<div class="admonition-note admonition">
  
注释
+
注解
  
Aggregation functions return <code>None</code> when used with an empty
+
与空 <code>QuerySet</code> 一起使用时,聚合函数返回 <code>None</code>。 例如,如果 <code>QuerySet</code> 不包含任何条目,则 <code>Sum</code> 聚合函数返回 <code>None</code> 而不是 <code>0</code>。 一个例外是 <code>Count</code>,如果 <code>QuerySet</code> 为空,它会返回 <code>0</code>
<code>QuerySet</code>. For example, the <code>Sum</code> aggregation function returns <code>None</code>
 
instead of <code>0</code> if the <code>QuerySet</code> contains no entries. An exception is
 
<code>Count</code>, which does return <code>0</code> if the <code>QuerySet</code> is empty.
 
  
  
 
</div>
 
</div>
All aggregates have the following parameters in common:
+
所有聚合体都有以下共同的参数:
  
 
<div id="expressions" class="section">
 
<div id="expressions" class="section">
  
==== <code>expressions</code> ====
+
==== expressions ====
  
Strings that reference fields on the model, or [[../expressions|<span class="doc">query expressions</span>]].
+
引用模型字段的字符串,或 [[../expressions|查询表达式]]
  
  
第5,013行: 第4,114行:
 
<div id="output-field" class="section">
 
<div id="output-field" class="section">
  
==== <code>output_field</code> ====
+
==== output_field ====
  
An optional argument that represents the [[../fields|<span class="doc">model field</span>]]
+
一个可选参数,表示返回值的 [[../fields|模型字段]]
of the return value
 
  
 
<div class="admonition note">
 
<div class="admonition note">
第5,022行: 第4,122行:
 
注解
 
注解
  
When combining multiple field types, Django can only determine the
+
在组合多个字段类型时,如果所有字段类型相同,Django 只能确定 <code>output_field</code>。 否则,您必须自己提供 <code>output_field</code>
<code>output_field</code> if all fields are of the same type. Otherwise, you
 
must provide the <code>output_field</code> yourself.
 
  
  
第5,032行: 第4,130行:
 
<div id="aggregate-filter" class="section">
 
<div id="aggregate-filter" class="section">
  
<span id="id6"></span>
+
<span id="id42"></span>
==== <code>filter</code> ====
+
==== filter ====
  
An optional [[#django.db.models.Q|<code>Q object</code>]] that's used to filter the
+
一个可选的 [[#django.db.models.Q|Q 对象]] ,用于过滤聚合的行。
rows that are aggregated.
 
  
See [[../conditional-expressions#conditional-aggregation|<span class="std std-ref">Conditional aggregation</span>]] and [[../../../topics/db/aggregation#filtering-on-annotations|<span class="std std-ref">过滤注解</span>]] for
+
有关示例用法,请参阅 [[../conditional-expressions#conditional-aggregation|条件聚合]] [[../../../topics/db/aggregation#filtering-on-annotations|注释过滤]]
example usage.
 
  
  
 
</div>
 
</div>
<div id="id7" class="section">
+
<div id="id43" class="section">
  
==== <code>**extra</code> ====
+
==== **extra ====
  
Keyword arguments that can provide extra context for the SQL generated
+
关键字参数,可以为聚合生成的 SQL 提供额外的上下文。
by the aggregate.
 
  
  
第5,054行: 第4,149行:
 
<div id="avg" class="section">
 
<div id="avg" class="section">
  
==== <code>Avg</code> ====
+
==== Avg ====
  
; ''class'' <code>Avg</code><span class="sig-paren">(</span>''<span class="n">expression</span>'', ''<span class="n">output_field</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">filter</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="o">**</span><span class="n">extra</span>''<span class="sig-paren">)</span>[[../../_modules/django/db/models/aggregates.html#Avg|<span class="viewcode-link">[源代码]</span>]]
+
; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">Avg</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">expression</span></span>'', ''<span class="n"><span class="pre">output_field</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">filter</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">extra</span></span>''<span class="sig-paren">)</span>
: Returns the mean value of the given expression, which must be numeric unless you specify a different <code>output_field</code>.
+
: 返回给定表达式的平均值,除非您指定不同的 <code>output_field</code>,否则该平均值必须是数字。
;* Default alias: <code>&lt;field&gt;__avg</code>
+
;* 默认别名:<code>&lt;field&gt;__avg</code>
;* Return type: <code>float</code> if input is <code>int</code>, otherwise same as input field, or <code>output_field</code> if supplied
+
;* 返回类型:<code>float</code> 如果输入是 <code>int</code>,否则与输入字段相同,或者 <code>output_field</code> 如果提供
  
  
 
</div>
 
</div>
<div id="id8" class="section">
+
<div id="id44" class="section">
  
==== <code>Count</code> ====
+
==== Count ====
  
 
<dl>
 
<dl>
<dt>''class'' <code>Count</code><span class="sig-paren">(</span>''<span class="n">expression</span>'', ''<span class="n">distinct</span><span class="o">=</span><span class="default_value">False</span>'', ''<span class="n">filter</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="o">**</span><span class="n">extra</span>''<span class="sig-paren">)</span>[[../../_modules/django/db/models/aggregates.html#Count|<span class="viewcode-link">[源代码]</span>]]</dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">Count</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">expression</span></span>'', ''<span class="n"><span class="pre">distinct</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span>'', ''<span class="n"><span class="pre">filter</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">extra</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Returns the number of objects that are related through the provided
+
<dd><p>返回通过提供的表达式关联的对象数量。</p>
expression.</p>
 
 
<ul>
 
<ul>
<li><p>Default alias: <code>&lt;field&gt;__count</code></p></li>
+
<li><p>默认别名:<code>&lt;field&gt;__count</code></p></li>
<li><p>Return type: <code>int</code></p></li></ul>
+
<li><p>返回类型:<code>int</code></p></li></ul>
  
 
<p>包含一个可选参数:</p>
 
<p>包含一个可选参数:</p>
 
<dl>
 
<dl>
<dt><code>distinct</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">distinct</span></span></dt>
<dd><p>If <code>distinct=True</code>, the count will only include unique instances.
+
<dd><p>如果为 <code>distinct=True</code>,则计数将仅包括唯一实例。 这是 <code>COUNT(DISTINCT &lt;field&gt;)</code> 的 SQL 等价物。 默认值为 <code>False</code></p></dd></dl>
This is the SQL equivalent of <code>COUNT(DISTINCT &lt;field&gt;)</code>. The default
 
value is <code>False</code>.</p></dd></dl>
 
 
</dd></dl>
 
</dd></dl>
  
第5,087行: 第4,179行:
 
<div id="max" class="section">
 
<div id="max" class="section">
  
==== <code>Max</code> ====
+
==== Max ====
  
; ''class'' <code>Max</code><span class="sig-paren">(</span>''<span class="n">expression</span>'', ''<span class="n">output_field</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">filter</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="o">**</span><span class="n">extra</span>''<span class="sig-paren">)</span>[[../../_modules/django/db/models/aggregates.html#Max|<span class="viewcode-link">[源代码]</span>]]
+
; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">Max</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">expression</span></span>'', ''<span class="n"><span class="pre">output_field</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">filter</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">extra</span></span>''<span class="sig-paren">)</span>
: Returns the maximum value of the given expression.
+
: 返回给定表达式的最大值。
;* Default alias: <code>&lt;field&gt;__max</code>
+
;* 默认别名:<code>&lt;field&gt;__max</code>
;* Return type: same as input field, or <code>output_field</code> if supplied
+
;* 返回类型:与输入字段相同,或 <code>output_field</code>(如果提供)
  
  
第5,098行: 第4,190行:
 
<div id="min" class="section">
 
<div id="min" class="section">
  
==== <code>Min</code> ====
+
==== Min ====
  
; ''class'' <code>Min</code><span class="sig-paren">(</span>''<span class="n">expression</span>'', ''<span class="n">output_field</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">filter</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="o">**</span><span class="n">extra</span>''<span class="sig-paren">)</span>[[../../_modules/django/db/models/aggregates.html#Min|<span class="viewcode-link">[源代码]</span>]]
+
; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">Min</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">expression</span></span>'', ''<span class="n"><span class="pre">output_field</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">filter</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">extra</span></span>''<span class="sig-paren">)</span>
: Returns the minimum value of the given expression.
+
: 返回给定表达式的最小值。
;* Default alias: <code>&lt;field&gt;__min</code>
+
;* 默认别名:<code>&lt;field&gt;__min</code>
;* Return type: same as input field, or <code>output_field</code> if supplied
+
;* 返回类型:与输入字段相同,或 <code>output_field</code>(如果提供)
  
  
第5,109行: 第4,201行:
 
<div id="stddev" class="section">
 
<div id="stddev" class="section">
  
==== <code>StdDev</code> ====
+
==== StdDev ====
  
 
<dl>
 
<dl>
<dt>''class'' <code>StdDev</code><span class="sig-paren">(</span>''<span class="n">expression</span>'', ''<span class="n">output_field</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">sample</span><span class="o">=</span><span class="default_value">False</span>'', ''<span class="n">filter</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="o">**</span><span class="n">extra</span>''<span class="sig-paren">)</span>[[../../_modules/django/db/models/aggregates.html#StdDev|<span class="viewcode-link">[源代码]</span>]]</dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">StdDev</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">expression</span></span>'', ''<span class="n"><span class="pre">output_field</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">sample</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span>'', ''<span class="n"><span class="pre">filter</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">extra</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Returns the standard deviation of the data in the provided expression.</p>
+
<dd><p>返回给定表达式中数据的标准差。</p>
 
<ul>
 
<ul>
<li><p>Default alias: <code>&lt;field&gt;__stddev</code></p></li>
+
<li><p>默认别名:<code>&lt;field&gt;__stddev</code></p></li>
<li><p>Return type: <code>float</code> if input is <code>int</code>, otherwise same as input
+
<li><p>返回类型:<code>float</code> 如果输入是 <code>int</code>,否则与输入字段相同,或者 <code>output_field</code> 如果提供</p></li></ul>
field, or <code>output_field</code> if supplied</p></li></ul>
 
  
 
<p>包含一个可选参数:</p>
 
<p>包含一个可选参数:</p>
 
<dl>
 
<dl>
<dt><code>sample</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">sample</span></span></dt>
<dd><p>By default, <code>StdDev</code> returns the population standard deviation. However,
+
<dd><p>默认情况下,<code>StdDev</code> 返回总体标准差。 但是,如果<code>sample=True</code>,则返回值将是样本标准差。</p></dd></dl>
if <code>sample=True</code>, the return value will be the sample standard deviation.</p></dd></dl>
 
  
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p>SQLite support was added.</p>
+
<p><span class="versionmodified changed">在 2.2 版更改:添加了 </span>SQLite 支持。</p>
  
 
</div></dd></dl>
 
</div></dd></dl>
第5,135行: 第4,225行:
 
<div id="sum" class="section">
 
<div id="sum" class="section">
  
==== <code>Sum</code> ====
+
==== Sum ====
  
; ''class'' <code>Sum</code><span class="sig-paren">(</span>''<span class="n">expression</span>'', ''<span class="n">output_field</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">filter</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="o">**</span><span class="n">extra</span>''<span class="sig-paren">)</span>[[../../_modules/django/db/models/aggregates.html#Sum|<span class="viewcode-link">[源代码]</span>]]
+
; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">Sum</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">expression</span></span>'', ''<span class="n"><span class="pre">output_field</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">filter</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">extra</span></span>''<span class="sig-paren">)</span>
: Computes the sum of all values of the given expression.
+
: 计算给定表达式的所有值的总和。
;* Default alias: <code>&lt;field&gt;__sum</code>
+
;* 默认别名:<code>&lt;field&gt;__sum</code>
;* Return type: same as input field, or <code>output_field</code> if supplied
+
;* 返回类型:与输入字段相同,或 <code>output_field</code>(如果提供)
  
  
第5,146行: 第4,236行:
 
<div id="variance" class="section">
 
<div id="variance" class="section">
  
==== <code>Variance</code> ====
+
==== Variance ====
  
 
<dl>
 
<dl>
<dt>''class'' <code>Variance</code><span class="sig-paren">(</span>''<span class="n">expression</span>'', ''<span class="n">output_field</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">sample</span><span class="o">=</span><span class="default_value">False</span>'', ''<span class="n">filter</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="o">**</span><span class="n">extra</span>''<span class="sig-paren">)</span>[[../../_modules/django/db/models/aggregates.html#Variance|<span class="viewcode-link">[源代码]</span>]]</dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">Variance</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">expression</span></span>'', ''<span class="n"><span class="pre">output_field</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">sample</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span>'', ''<span class="n"><span class="pre">filter</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">extra</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Returns the variance of the data in the provided expression.</p>
+
<dd><p>返回给定表达式中数据的方差。</p>
 
<ul>
 
<ul>
<li><p>Default alias: <code>&lt;field&gt;__variance</code></p></li>
+
<li><p>默认别名:<code>&lt;field&gt;__variance</code></p></li>
<li><p>Return type: <code>float</code> if input is <code>int</code>, otherwise same as input
+
<li><p>返回类型:<code>float</code> 如果输入是 <code>int</code>,否则与输入字段相同,或者 <code>output_field</code> 如果提供</p></li></ul>
field, or <code>output_field</code> if supplied</p></li></ul>
 
  
 
<p>包含一个可选参数:</p>
 
<p>包含一个可选参数:</p>
 
<dl>
 
<dl>
<dt><code>sample</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">sample</span></span></dt>
<dd><p>By default, <code>Variance</code> returns the population variance. However,
+
<dd><p>默认情况下,<code>Variance</code> 返回总体方差。 但是,如果<code>sample=True</code>,返回值将是样本方差。</p></dd></dl>
if <code>sample=True</code>, the return value will be the sample variance.</p></dd></dl>
 
  
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p>SQLite support was added.</p>
+
<p><span class="versionmodified changed">在 2.2 版更改:添加了 </span>SQLite 支持。</p>
  
 
</div></dd></dl>
 
</div></dd></dl>
第5,176行: 第4,264行:
 
<div id="query-related-tools" class="section">
 
<div id="query-related-tools" class="section">
  
== Query-related tools ==
+
== 查询相关工具 ==
  
This section provides reference material for query-related tools not documented
+
本节提供了与查询相关的工具的参考资料,其他地方没有记载。
elsewhere.
 
  
 
<div id="q-objects" class="section">
 
<div id="q-objects" class="section">
  
=== <code>Q()</code> objects ===
+
=== Q() 物体 ===
  
; ''class'' <code>Q</code>[[../../_modules/django/db/models/query_utils.html#Q|<span class="viewcode-link">[源代码]</span>]]
+
; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">Q</span></span>
 
:  
 
:  
  
A <code>Q()</code> object, like an [[../expressions#django.db.models|<code>F</code>]] object, encapsulates a
+
<code>Q()</code> 对象,如 [[../expressions#django.db.models|F]] 对象,将 SQL 表达式封装在 Python 对象中,可用于数据库相关操作。
SQL expression in a Python object that can be used in database-related
 
operations.
 
  
In general, <code>Q() objects</code> make it possible to define and reuse conditions.
+
通常,<code>Q() objects</code> 可以定义和重用条件。 这允许使用 <code>|</code> (<code>OR</code>) <code>&amp;</code> (<code>AND</code>) 运算符构建复杂数据库查询 [[../../../topics/db/queries#complex-lookups-with-q|的]] ; 特别是,不能在 <code>QuerySets</code> 中使用 <code>OR</code>
This permits the [[../../../topics/db/queries#complex-lookups-with-q|<span class="std std-ref">construction of complex database queries</span>]] using <code>|</code> (<code>OR</code>) and <code>&amp;</code> (<code>AND</code>) operators;
 
in particular, it is not otherwise possible to use <code>OR</code> in <code>QuerySets</code>.
 
  
  
第5,200行: 第4,283行:
 
<div id="prefetch-objects" class="section">
 
<div id="prefetch-objects" class="section">
  
=== <code>Prefetch()</code> objects ===
+
=== Prefetch() 物体 ===
  
; ''class'' <code>Prefetch</code><span class="sig-paren">(</span>''<span class="n">lookup</span>'', ''<span class="n">queryset</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">to_attr</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span>[[../../_modules/django/db/models/query.html#Prefetch|<span class="viewcode-link">[源代码]</span>]]
+
; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">Prefetch</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">lookup</span></span>'', ''<span class="n"><span class="pre">queryset</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">to_attr</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
The <code>Prefetch()</code> object can be used to control the operation of
+
<code>Prefetch()</code> 对象可用于控制 [[#django.db.models.query.QuerySet.prefetch_related|prefetch_related()]] 的操作。
[[#django.db.models.query.QuerySet.prefetch_related|<code>prefetch_related()</code>]].
 
  
The <code>lookup</code> argument describes the relations to follow and works the same
+
<code>lookup</code> 参数描述了要遵循的关系,其工作方式与传递给 [[#django.db.models.query.QuerySet.prefetch_related|prefetch_related()]] 的基于字符串的查找相同。 例如:
as the string based lookups passed to
 
[[#django.db.models.query.QuerySet.prefetch_related|<code>prefetch_related()</code>]]. For example:
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第5,216行: 第4,296行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; from django.db.models import Prefetch
+
<syntaxhighlight lang="python">>>> from django.db.models import Prefetch
&gt;&gt;&gt; Question.objects.prefetch_related(Prefetch('choice_set')).get().choice_set.all()
+
>>> Question.objects.prefetch_related(Prefetch('choice_set')).get().choice_set.all()
&lt;QuerySet [&lt;Choice: Not much&gt;, &lt;Choice: The sky&gt;, &lt;Choice: Just hacking again&gt;]&gt;
+
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
 
# This will only execute two queries regardless of the number of Question
 
# This will only execute two queries regardless of the number of Question
 
# and Choice objects.
 
# and Choice objects.
&gt;&gt;&gt; Question.objects.prefetch_related(Prefetch('choice_set')).all()
+
>>> Question.objects.prefetch_related(Prefetch('choice_set')).all()
&lt;QuerySet [&lt;Question: What's up?&gt;]&gt;</pre>
+
<QuerySet [<Question: What's up?>]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The <code>queryset</code> argument supplies a base <code>QuerySet</code> for the given lookup.
+
<code>queryset</code> 参数为给定的查找提供一个基本的 <code>QuerySet</code>。 这对于进一步过滤预取操作或从预取关系调用 [[#django.db.models.query.QuerySet.select_related|select_related()]] 很有用,从而进一步减少查询次数:
This is useful to further filter down the prefetch operation, or to call
 
[[#django.db.models.query.QuerySet.select_related|<code>select_related()</code>]] from the prefetched
 
relation, hence reducing the number of queries even further:
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第5,236行: 第4,313行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; voted_choices = Choice.objects.filter(votes__gt=0)
+
<syntaxhighlight lang="python">>>> voted_choices = Choice.objects.filter(votes__gt=0)
&gt;&gt;&gt; voted_choices
+
>>> voted_choices
&lt;QuerySet [&lt;Choice: The sky&gt;]&gt;
+
<QuerySet [<Choice: The sky>]>
&gt;&gt;&gt; prefetch = Prefetch('choice_set', queryset=voted_choices)
+
>>> prefetch = Prefetch('choice_set', queryset=voted_choices)
&gt;&gt;&gt; Question.objects.prefetch_related(prefetch).get().choice_set.all()
+
>>> Question.objects.prefetch_related(prefetch).get().choice_set.all()
&lt;QuerySet [&lt;Choice: The sky&gt;]&gt;</pre>
+
<QuerySet [<Choice: The sky>]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The <code>to_attr</code> argument sets the result of the prefetch operation to a custom
+
<code>to_attr</code> 参数将预取操作的结果设置为自定义属性:
attribute:
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第5,253行: 第4,329行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; prefetch = Prefetch('choice_set', queryset=voted_choices, to_attr='voted_choices')
+
<syntaxhighlight lang="python">>>> prefetch = Prefetch('choice_set', queryset=voted_choices, to_attr='voted_choices')
&gt;&gt;&gt; Question.objects.prefetch_related(prefetch).get().voted_choices
+
>>> Question.objects.prefetch_related(prefetch).get().voted_choices
[&lt;Choice: The sky&gt;]
+
[<Choice: The sky>]
&gt;&gt;&gt; Question.objects.prefetch_related(prefetch).get().choice_set.all()
+
>>> Question.objects.prefetch_related(prefetch).get().choice_set.all()
&lt;QuerySet [&lt;Choice: Not much&gt;, &lt;Choice: The sky&gt;, &lt;Choice: Just hacking again&gt;]&gt;</pre>
+
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]></syntaxhighlight>
  
 
</div>
 
</div>
第5,266行: 第4,342行:
 
注解
 
注解
  
When using <code>to_attr</code> the prefetched result is stored in a list. This can
+
使用 <code>to_attr</code> 时,预取结果存储在列表中。 与将缓存结果存储在 <code>QuerySet</code> 实例中的传统 <code>prefetch_related</code> 调用相比,这可以显着提高速度。
provide a significant speed improvement over traditional
 
<code>prefetch_related</code> calls which store the cached result within a
 
<code>QuerySet</code> instance.
 
  
  
第5,277行: 第4,350行:
 
<div id="prefetch-related-objects" class="section">
 
<div id="prefetch-related-objects" class="section">
  
=== <code>prefetch_related_objects()</code> ===
+
=== prefetch_related_objects() ===
  
; <code>prefetch_related_objects</code><span class="sig-paren">(</span>''<span class="n">model_instances</span>'', ''<span class="o">*</span><span class="n">related_lookups</span>''<span class="sig-paren">)</span>[[../../_modules/django/db/models/query.html#prefetch_related_objects|<span class="viewcode-link">[源代码]</span>]]
+
; <span class="sig-name descname"><span class="pre">prefetch_related_objects</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">model_instances</span></span>'', ''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">related_lookups</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Prefetches the given lookups on an iterable of model instances. This is useful
+
在可迭代的模型实例上预取给定的查找。 这在接收模型实例列表而不是 <code>QuerySet</code> 的代码中很有用; 例如,从缓存中获取模型或手动实例化它们时。
in code that receives a list of model instances as opposed to a <code>QuerySet</code>;
 
for example, when fetching models from a cache or instantiating them manually.
 
  
Pass an iterable of model instances (must all be of the same class) and the
+
传递模型实例的可迭代对象(必须都属于同一类)和要预取的查找或 [[#django.db.models.Prefetch|Prefetch]] 对象。 例如:
lookups or [[#django.db.models.Prefetch|<code>Prefetch</code>]] objects you want to prefetch for. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第5,293行: 第4,363行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; from django.db.models import prefetch_related_objects
+
<syntaxhighlight lang="python">>>> from django.db.models import prefetch_related_objects
&gt;&gt;&gt; restaurants = fetch_top_restaurants_from_cache()  # A list of Restaurants
+
>>> restaurants = fetch_top_restaurants_from_cache()  # A list of Restaurants
&gt;&gt;&gt; prefetch_related_objects(restaurants, 'pizzas__toppings')</pre>
+
>>> prefetch_related_objects(restaurants, 'pizzas__toppings')</syntaxhighlight>
  
 
</div>
 
</div>
第5,304行: 第4,374行:
 
<div id="filteredrelation-objects" class="section">
 
<div id="filteredrelation-objects" class="section">
  
=== <code>FilteredRelation()</code> objects ===
+
=== FilteredRelation() 物体 ===
  
 
<dl>
 
<dl>
<dt>''class'' <code>FilteredRelation</code><span class="sig-paren">(</span>''<span class="n">relation_name</span>'', ''<span class="o">*</span>'', ''<span class="n">condition</span><span class="o">=</span><span class="default_value">Q()</span>''<span class="sig-paren">)</span>[[../../_modules/django/db/models/query_utils.html#FilteredRelation|<span class="viewcode-link">[源代码]</span>]]</dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">FilteredRelation</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">relation_name</span></span>'', ''<span class="o"><span class="pre">*</span></span>'', ''<span class="n"><span class="pre">condition</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">Q()</span></span>''<span class="sig-paren">)</span></dt>
 
<dd><dl>
 
<dd><dl>
<dt><code>relation_name</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">relation_name</span></span></dt>
<dd><p>The name of the field on which you'd like to filter the relation.</p></dd></dl>
+
<dd><p>您要过滤关系的字段的名称。</p></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>condition</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">condition</span></span></dt>
<dd><p>A [[#django.db.models.Q|<code>Q</code>]] object to control the filtering.</p></dd></dl>
+
<dd><p>一个 [[#django.db.models.Q|Q]] 对象来控制过滤。</p></dd></dl>
 
</dd></dl>
 
</dd></dl>
  
<code>FilteredRelation</code> is used with [[#django.db.models.query.QuerySet.annotate|<code>annotate()</code>]] to create an
+
<code>FilteredRelation</code> [[#django.db.models.query.QuerySet.annotate|annotate()]] 一起使用,以在执行 <code>JOIN</code> 时创建 <code>ON</code> 子句。 它不作用于默认关系,而是作用于注释名称(下面示例中的 <code>pizzas_vegetarian</code>)。
<code>ON</code> clause when a <code>JOIN</code> is performed. It doesn't act on the default
 
relationship but on the annotation name (<code>pizzas_vegetarian</code> in example
 
below).
 
  
For example, to find restaurants that have vegetarian pizzas with
+
例如,要查找名称中包含 <code>'mozzarella'</code> 的素食比萨饼的餐厅:
<code>'mozzarella'</code> in the name:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第5,329行: 第4,395行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; from django.db.models import FilteredRelation, Q
+
<syntaxhighlight lang="python">>>> from django.db.models import FilteredRelation, Q
&gt;&gt;&gt; Restaurant.objects.annotate(
+
>>> Restaurant.objects.annotate(
 
...    pizzas_vegetarian=FilteredRelation(
 
...    pizzas_vegetarian=FilteredRelation(
 
...        'pizzas', condition=Q(pizzas__vegetarian=True),
 
...        'pizzas', condition=Q(pizzas__vegetarian=True),
 
...    ),
 
...    ),
... ).filter(pizzas_vegetarian__name__icontains='mozzarella')</pre>
+
... ).filter(pizzas_vegetarian__name__icontains='mozzarella')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
If there are a large number of pizzas, this queryset performs better than:
+
如果有大量比萨饼,则此查询集的性能优于:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第5,345行: 第4,411行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Restaurant.objects.filter(
+
<syntaxhighlight lang="python">>>> Restaurant.objects.filter(
 
...    pizzas__vegetarian=True,
 
...    pizzas__vegetarian=True,
 
...    pizzas__name__icontains='mozzarella',
 
...    pizzas__name__icontains='mozzarella',
... )</pre>
+
... )</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
because the filtering in the <code>WHERE</code> clause of the first queryset will only
+
因为第一个查询集的 <code>WHERE</code> 子句中的过滤只会对素食比萨进行操作。
operate on vegetarian pizzas.
 
  
<code>FilteredRelation</code> doesn't support:
+
<code>FilteredRelation</code> 不支持:
  
 
<ul>
 
<ul>
<li><p>Conditions that span relational fields. For example:</p>
+
<li><p>跨越关系字段的条件。 例如:</p>
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Restaurant.objects.annotate(
+
<syntaxhighlight lang="python">>>> Restaurant.objects.annotate(
 
...    pizzas_with_toppings_startswith_n=FilteredRelation(
 
...    pizzas_with_toppings_startswith_n=FilteredRelation(
 
...        'pizzas__toppings',
 
...        'pizzas__toppings',
第5,372行: 第4,437行:
 
Traceback (most recent call last):
 
Traceback (most recent call last):
 
...
 
...
ValueError: FilteredRelation's condition doesn't support nested relations (got 'pizzas__toppings__name__startswith').</pre>
+
ValueError: FilteredRelation's condition doesn't support nested relations (got 'pizzas__toppings__name__startswith').</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div></li>
 
</div></li>
<li><p>[[#django.db.models.query.QuerySet.only|<code>QuerySet.only()</code>]] and [[#django.db.models.query.QuerySet.prefetch_related|<code>prefetch_related()</code>]].</p></li>
+
<li><p>[[#django.db.models.query.QuerySet.only|QuerySet.only()]] [[#django.db.models.query.QuerySet.prefetch_related|prefetch_related()]]</p></li>
<li><p>A [[../../contrib/contenttypes#django.contrib.contenttypes.fields|<code>GenericForeignKey</code>]]
+
<li><p>从父模型继承的 [[../../contrib/contenttypes#django.contrib.contenttypes.fields|GenericForeignKey]]</p></li></ul>
inherited from a parent model.</p></li></ul>
 
  
  
第5,385行: 第4,449行:
  
 
</div>
 
</div>
 +
 +
</div>
 +
<div class="clearer">
 +
 +
  
 
</div>
 
</div>
  
[[Category:Django 2.2.x 中文文档]]
+
[[Category:Django 2.2.x 文档]]

2021年10月31日 (日) 04:05的最新版本

QuerySet API 参考

本文档描述了 QuerySet API 的详细信息。 它建立在 模型数据库查询 指南中提供的材料之上,因此您可能希望在阅读本文之前先阅读并理解这些文档。

在本参考文献中,我们将使用 数据库查询指南 中介绍的 示例网络日志模型

当评估 QuerySets 时

在内部,QuerySet 可以被构造、过滤、切片,并且通常在不实际访问数据库的情况下传递。 在您执行某些操作来评估查询集之前,实际上不会发生数据库活动。

您可以通过以下方式评估 QuerySet

  • Iteration. QuerySet 是可迭代的,它会在您第一次对其进行迭代时执行其数据库查询。 例如,这将打印数据库中所有条目的标题:

    for e in Entry.objects.all():
        print(e.headline)

    注意:如果您只想确定是否存在至少一个结果,请不要使用此选项。 使用 exists() 效率更高。

  • 切片。Limiting QuerySets 中所述,可以使用 Python 的数组切片语法对 QuerySet 进行切片。 切片一个未赋值的 QuerySet 通常会返回另一个未赋值的 QuerySet,但如果使用切片语法的“step”参数,Django 将执行数据库查询,并返回一个列表。 对已求值的 QuerySet 进行切片也会返回一个列表。

    另请注意,即使切片未计算的 QuerySet 返回另一个未计算的 QuerySet,也不允许进一步修改(例如,添加更多过滤器或修改排序),因为这不能很好地转换为 SQL它也不会有明确的含义。

  • Pickling/Caching. pickling QuerySets 时所涉及的详细信息,请参阅以下部分。 就本节而言,重要的是从数据库中读取结果。

  • repr(). 当您调用 repr() 时,会评估 QuerySet。 这是为了方便 Python 交互式解释器,因此您可以在交互式使用 API 时立即看到结果。

  • len(). 当您调用 len() 时,会评估 QuerySet。 正如您所料,这将返回结果列表的长度。

    注意:如果您只需要确定集合中的记录数(而不需要实际对象),使用 SQL 的 SELECT COUNT(*) 在数据库级别处理计数会更有效。 正是出于这个原因,Django 提供了一个 count() 方法。

  • list(). 通过调用 list() 强制评估 QuerySet。 例如:

    entry_list = list(Entry.objects.all())
  • bool(). 在布尔上下文中测试 QuerySet,例如使用 bool()orandif 语句,将导致执行查询。 如果至少有一个结果,则QuerySetTrue,否则为False。 例如:

    if Entry.objects.filter(headline="Test"):
       print("There is at least one Entry with the headline Test")

    注意:如果您只想确定是否至少存在一个结果(并且不需要实际对象),则使用 exists() 更有效。

酸洗 QuerySets

如果你 pickle a QuerySet,这将强制所有结果在酸洗之前加载到内存中。 酸洗通常用作缓存的前兆,当重新加载缓存的查询集时,您希望结果已经存在并可供使用(从数据库中读取可能需要一些时间,违背了缓存的目的)。 这意味着当你 unpickle 一个 QuerySet 时,它包含它被pickle 时的结果,而不是当前在数据库中的结果。

如果您只想在稍后从数据库中腌制必要的信息以重新创建 QuerySet,请腌制 QuerySetquery 属性。 然后,您可以使用如下代码重新创建原始 QuerySet(不加载任何结果):

>>> import pickle
>>> query = pickle.loads(s)     # Assuming 's' is the pickled string.
>>> qs = MyModel.objects.all()
>>> qs.query = query            # Restore the original 'query'.

query 属性是一个不透明的对象。 它代表查询构造的内部结构,而不是公共 API 的一部分。 但是,按照此处所述对属性的内容进行pickle 和unpickle 是安全的(并且完全受支持)。

您不能在版本之间共享泡菜

QuerySets 的泡菜仅对用于生成它们的 Django 版本有效。 如果您使用 Django 版本 N 生成 pickle,则无法保证使用 Django N+1 版本可以读取 pickle。 不应将泡菜用作长期存档策略的一部分。

由于pickle 兼容性错误可能难以诊断,例如静默损坏的对象,因此当您尝试在与pickle 版本不同的Django 版本中对查询集进行unpickle 时,会引发RuntimeWarning


QuerySet API

这是 QuerySet 的正式声明:

class QuerySet(model=None, query=None, using=None, hints=None)

通常,当您与 QuerySet 交互时,您会通过 链接过滤器 来使用它。 为了完成这项工作,大多数 QuerySet 方法返回新的查询集。 本节稍后将详细介绍这些方法。

QuerySet 类有两个可用于自省的公共属性:

ordered

True 如果订购了 QuerySet — 即 在模型上有一个 order_by() 子句或默认排序。 False 否则。

db

如果现在执行这个查询,将使用的数据库。

注解

QuerySetquery 参数存在以便专门的查询子类可以重建内部查询状态。 该参数的值是该查询状态的不透明表示,不是公共 API 的一部分。 简单地说:如果你需要问,你不需要使用它。

返回新 QuerySet 的方法

Django 提供了一系列 QuerySet 细化方法,可以修改 QuerySet 返回的结果类型或其 SQL 查询的执行方式。

filter()

filter(**kwargs)

返回包含与给定查找参数匹配的对象的新 QuerySet

查找参数 (**kwargs) 应采用以下 字段查找 中描述的格式。 多个参数通过底层 SQL 语句中的 AND 连接。

如果您需要执行更复杂的查询(例如,使用 OR 语句的查询),您可以使用 Q 对象


exclude()

exclude(**kwargs)

返回一个新的 QuerySet,其中包含 不匹配给定查找参数的对象。

查找参数 (**kwargs) 应采用以下 字段查找 中描述的格式。 多个参数通过底层 SQL 语句中的 AND 连接起来,整个内容包含在一个 NOT() 中。

此示例排除 pub_date 晚于 2005-1-3 且 headline 为“Hello”的所有条目:

Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello')

在 SQL 术语中,计算结果为:

SELECT ...
WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello')

此示例排除 pub_date 晚于 2005-1-3 或标题为“您好”的所有条目:

Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3)).exclude(headline='Hello')

在 SQL 术语中,计算结果为:

SELECT ...
WHERE NOT pub_date > '2005-1-3'
AND NOT headline = 'Hello'

请注意,第二个例子的限制性更强。

如果您需要执行更复杂的查询(例如,使用 OR 语句的查询),您可以使用 Q 对象


annotate()

annotate(*args, **kwargs)

使用提供的 查询表达式 列表注释 QuerySet 中的每个对象。 表达式可以是一个简单的值、对模型(或任何相关模型)上的字段的引用,或者是对与模型中的对象相关的对象进行计算的聚合表达式(平均值、总和等)。 QuerySet

annotate() 的每个参数都是一个注释,将添加到返回的 QuerySet 中的每个对象。

Django 提供的聚合函数在下面的 Aggregation Functions 中描述。

使用关键字参数指定的注释将使用关键字作为注释的别名。 匿名参数将根据聚合函数的名称和正在聚合的模型字段为它们生成一个别名。 只有引用单个字段的聚合表达式才能是匿名参数。 其他所有内容都必须是关键字参数。

例如,如果您正在操作一个博客列表,您可能想要确定每个博客中已经创建了多少条目:

>>> from django.db.models import Count
>>> q = Blog.objects.annotate(Count('entry'))
# The name of the first blog
>>> q[0].name
'Blogasaurus'
# The number of entries on the first blog
>>> q[0].entry__count
42

Blog 模型本身并没有定义 entry__count 属性,但是通过使用关键字参数指定聚合函数,您可以控制注解的名称:

>>> q = Blog.objects.annotate(number_of_entries=Count('entry'))
# The number of entries on the first blog, using the name provided
>>> q[0].number_of_entries
42

有关聚合的深入讨论,请参阅 有关聚合的主题指南


order_by()

order_by(*fields)

默认情况下,QuerySet 返回的结果按模型的 Meta 中的 ordering 选项给出的排序元组排序。 您可以使用 order_by 方法在每个 QuerySet 的基础上覆盖它。

例子:

Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline')

上面的结果将按 pub_date 降序排列,然后按 headline 升序排列。 "-pub_date"前面的负号表示降序。 升序是隐含的。 要随机排序,请使用 "?",如下所示:

Entry.objects.order_by('?')

注意:order_by('?') 查询可能既昂贵又缓慢,具体取决于您使用的数据库后端。

要按不同模型中的字段排序,请使用与跨模型关系查询时相同的语法。 即,字段名称,后跟双下划线 (__),后跟新模型中的字段名称,依此类推,适用于您想要加入的模型。 例如:

Entry.objects.order_by('blog__name', 'headline')

如果您尝试按与另一个模型相关的字段排序,Django 将使用相关模型的默认排序,或者如果未指定 Meta.ordering,则按相关模型的主键排序。 例如,由于 Blog 模型没有指定默认排序:

Entry.objects.order_by('blog')

……等同于:

Entry.objects.order_by('blog__id')

如果 Blogordering = ['name'],那么第一个查询集将等同于:

Entry.objects.order_by('blog__name')

您还可以通过在表达式上调用 asc()desc() 来按 查询表达式 排序:

Entry.objects.order_by(Coalesce('summary', 'headline').desc())

asc()desc() 具有控制空值排序方式的参数(nulls_firstnulls_last)。

如果您还使用 distinct(),则在按相关模型中的字段排序时要小心。 有关相关模型排序如何改变预期结果的说明,请参阅 distinct() 中的注释。

注解

允许指定多值字段以对结果进行排序(例如,ManyToManyField 字段,或 ForeignKey 字段的反向关系)。

考虑这个案例:

class Event(Model):
   parent = models.ForeignKey(
       'self',
       on_delete=models.CASCADE,
       related_name='children',
   )
   date = models.DateField()

Event.objects.order_by('children__date')

在这里,每个 Event 可能有多个排序数据; 每个带有多个 childrenEvent 将多次返回到 order_by() 创建的新 QuerySet 中。 换句话说,在 QuerySet 上使用 order_by() 可能会返回比您开始时更多的项目 - 这可能既不符合预期也没有用。

因此,在使用多值字段对结果进行排序时要小心。 如果您可以确定您订购的每件商品只有一个订购数据,那么这种方法应该不会出现问题。 如果没有,请确保结果符合您的预期。


无法指定排序是否应区分大小写。 关于区分大小写,Django 会对结果进行排序,但您的数据库后端通常会对其进行排序。

您可以使用 Lower 将字段转换为小写,这将实现大小写一致的排序:

Entry.objects.order_by(Lower('headline').desc())

如果您不希望对查询应用任何排序,甚至不希望应用默认排序,请调用不带参数的 order_by()

您可以通过检查 QuerySet.ordered 属性来判断查询是否已排序,如果 QuerySet 已以任何方式排序,则该属性将为 True

每个 order_by() 调用将清除任何先前的排序。 例如,此查询将按 pub_date 而不是 headline 排序:

Entry.objects.order_by('headline').order_by('pub_date')

警告

订购不是免费的操作。 您添加到排序中的每个字段都会对您的数据库产生成本。 您添加的每个外键也将隐式包含其所有默认排序。

如果查询未指定排序,则以未指定的顺序从数据库返回结果。 只有在按唯一标识结果中每个对象的一组字段进行排序时,才能保证特定的排序。 例如,如果 name 字段不是唯一的,按它排序并不能保证具有相同名称的对象总是以相同的顺序出现。


reverse()

reverse()

使用 reverse() 方法反转查询集元素的返回顺序。 再次调用 reverse() 会将排序恢复到正常方向。

要检索查询集中的“最后”五个项目,您可以这样做:

my_queryset.reverse()[:5]

请注意,这与在 Python 中从序列末尾进行切片并不完全相同。 上面的例子将首先返回最后一项,然后是倒数第二项,依此类推。 如果我们有一个 Python 序列并查看 seq[-5:],我们将首先看到倒数第五项。 Django 不支持这种访问模式(从末尾切片),因为在 SQL 中不可能有效地做到这一点。

另外,请注意 reverse() 通常只应在具有定义排序的 QuerySet 上调用(例如,当查询定义默认排序的模型时,或使用 order_by( ))。 如果没有为给定的 QuerySet 定义这样的排序,则对其调用 reverse() 没有实际影响(排序在调用 reverse() 之前未定义,之后将保持未定义) .


distinct()

distinct(*fields)

返回在其 SQL 查询中使用 SELECT DISTINCT 的新 QuerySet。 这消除了查询结果中的重复行。

默认情况下,QuerySet 不会消除重复行。 在实践中,这很少成为问题,因为像 Blog.objects.all() 这样的简单查询不会引入重复结果行的可能性。 但是,如果您的查询跨越多个表,则在评估 QuerySet 时可能会得到重复的结果。 那时你会使用 distinct()

注解

order_by() 调用中使用的任何字段都包含在 SQL SELECT 列中。 当与 distinct() 结合使用时,有时会导致意外结果。 如果您按相关模型中的字段排序,这些字段将被添加到选定的列中,否则它们可能会使重复的行看起来不同。 由于额外的列不会出现在返回的结果中(它们仅用于支持排序),因此有时看起来返回的是非不同的结果。

同样,如果您使用 values() 查询来限制选择的列,则任何 order_by()(或默认模型排序)中使用的列仍将涉及并可能影响唯一性的结果。

这里的寓意是,如果您使用 distinct(),请注意按相关型号排序。 同样,当一起使用 distinct()values() 时,按不在 values() 调用中的字段排序时要小心。


仅在 PostgreSQL 上,您可以传递位置参数 (*fields) 以指定 DISTINCT 应适用的字段名称。 这将转换为 SELECT DISTINCT ON SQL 查询。 这就是不同之处。 对于正常的 distinct() 调用,数据库在确定哪些行不同时比较每行中的 each 字段。 对于具有指定字段名称的 distinct() 调用,数据库将仅比较指定的字段名称。

注解

指定字段名称时,必须QuerySet中提供order_by()order_by()中的字段必须以distinct(),顺序相同。

例如,SELECT DISTINCT ON (a) 为您提供 a 列中每个值的第一行。 如果您不指定顺序,您将得到一些任意行。


示例(第一个之后的仅适用于 PostgreSQL):

>>> Author.objects.distinct()
[...]

>>> Entry.objects.order_by('pub_date').distinct('pub_date')
[...]

>>> Entry.objects.order_by('blog').distinct('blog')
[...]

>>> Entry.objects.order_by('author', 'pub_date').distinct('author', 'pub_date')
[...]

>>> Entry.objects.order_by('blog__name', 'mod_date').distinct('blog__name', 'mod_date')
[...]

>>> Entry.objects.order_by('author', 'pub_date').distinct('author')
[...]

注解

请记住, order_by() 使用已定义的任何默认相关模型排序。 您可能必须按关系 _id 或引用字段显式排序,以确保 DISTINCT ON 表达式与 ORDER BY 子句开头的表达式匹配。 例如,如果 Blog 模型通过 name 定义了一个 ordering

Entry.objects.order_by('blog').distinct('blog')

……不起作用,因为查询将按 blog__name 排序,从而与 DISTINCT ON 表达式不匹配。 您必须按关系 _id 字段(在本例中为 blog_id)或引用的字段(blog__pk)明确排序,以确保两个表达式匹配。


values()

values(*fields, **expressions)

返回一个 QuerySet 返回字典,而不是模型实例。

其中每一个字典都代表一个对象,键与模型对象的属性名相对应。

本示例将 values() 的字典与普通模型对象进行比较:

# This list contains a Blog object.
>>> Blog.objects.filter(name__startswith='Beatles')
<QuerySet [<Blog: Beatles Blog>]>

# This list contains a dictionary.
>>> Blog.objects.filter(name__startswith='Beatles').values()
<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]>

values() 方法采用可选的位置参数 *fields,它指定 SELECT 应限制为的字段名称。 如果您指定字段,则每个字典将仅包含您指定的字段的字段键/值。 如果不指定字段,则每个字典将包含数据库表中每个字段的键和值。

例子:

>>> Blog.objects.values()
<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]>
>>> Blog.objects.values('id', 'name')
<QuerySet [{'id': 1, 'name': 'Beatles Blog'}]>

values() 方法还接受可选的关键字参数,**expressions,这些参数被传递给 annotate()

>>> from django.db.models.functions import Lower
>>> Blog.objects.values(lower_name=Lower('name'))
<QuerySet [{'lower_name': 'beatles blog'}]>

您可以在排序中使用内置和 自定义查找 。 例如:

>>> from django.db.models import CharField
>>> from django.db.models.functions import Lower
>>> CharField.register_lookup(Lower)
>>> Blog.objects.values('name__lower')
<QuerySet [{'name__lower': 'beatles blog'}]>

2.1 版更改: 添加了对查找的支持。


values() 子句中的聚合应用在同一 values() 子句中的其他参数之前。 如果您需要按另一个值分组,请将其添加到较早的 values() 子句中。 例如:

>>> from django.db.models import Count
>>> Blog.objects.values('entry__authors', entries=Count('entry'))
<QuerySet [{'entry__authors': 1, 'entries': 20}, {'entry__authors': 1, 'entries': 13}]>
>>> Blog.objects.values('entry__authors').annotate(entries=Count('entry'))
<QuerySet [{'entry__authors': 1, 'entries': 33}]>

有几个微妙的地方值得一提:

  • 如果您有一个名为 foo 的字段,它是一个 ForeignKey,默认的 values() 调用将返回一个名为 foo_id 的字典键,因为这是名称存储实际值的隐藏模型属性(foo 属性指的是相关模型)。 当你调用 values() 并传入字段名称时,你可以传入 foofoo_id 并且你会得到同样的东西(字典键将匹配字段您传入的名称)。

    例如:

    >>> Entry.objects.values()
    <QuerySet [{'blog_id': 1, 'headline': 'First Entry', ...}, ...]>
    
    >>> Entry.objects.values('blog')
    <QuerySet [{'blog': 1}, ...]>
    
    >>> Entry.objects.values('blog_id')
    <QuerySet [{'blog_id': 1}, ...]>
  • values()distinct() 一起使用时,请注意排序会影响结果。 有关详细信息,请参阅 distinct() 中的注释。

  • 如果在 extra() 调用后使用 values() 子句,则 extra() 中由 select 参数定义的任何字段必须明确包含在 values() 调用中。 在 values() 调用之后进行的任何 extra() 调用都将忽略其额外的选定字段。

  • values() 之后调用 only()defer() 没有意义,因此这样做会引发 NotImplementedError

  • 组合转换和聚合需要使用两个 annotate() 调用,明确地或作为 values() 的关键字参数。 如上,如果转换已在相关字段类型上注册,则第一个 annotate() 可以省略,因此以下示例是等效的:

    >>> from django.db.models import CharField, Count
    >>> from django.db.models.functions import Lower
    >>> CharField.register_lookup(Lower)
    >>> Blog.objects.values('entry__authors__name__lower').annotate(entries=Count('entry'))
    <QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]>
    >>> Blog.objects.values(
    ...     entry__authors__name__lower=Lower('entry__authors__name')
    ... ).annotate(entries=Count('entry'))
    <QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]>
    >>> Blog.objects.annotate(
    ...     entry__authors__name__lower=Lower('entry__authors__name')
    ... ).values('entry__authors__name__lower').annotate(entries=Count('entry'))
    <QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]>

当您知道只需要少量可用字段中的值并且不需要模型实例对象的功能时,它很有用。 仅选择需要使用的字段会更有效率。

最后,注意可以调用filter()order_by()等。 在 values() 调用之后,这意味着这两个调用是相同的:

Blog.objects.values().order_by('id')
Blog.objects.order_by('id').values()

制作 Django 的人更喜欢将所有影响 SQL 的方法放在第一位,然后(可选)任何影响输出的方法(例如 values()),但这并不重要。 这是你真正炫耀个人主义的机会。

您还可以通过 OneToOneFieldForeignKeyManyToManyField 属性引用具有反向关系的相关模型上的字段:

>>> Blog.objects.values('name', 'entry__headline')
<QuerySet [{'name': 'My blog', 'entry__headline': 'An entry'},
     {'name': 'My blog', 'entry__headline': 'Another entry'}, ...]>

警告

因为 ManyToManyField 属性和反向关系可以有多个相关行,包括这些可以对结果集的大小产生乘数效应。 如果您在 values() 查询中包含多个这样的字段,这将特别明显,在这种情况下,将返回所有可能的组合。


values_list()

values_list(*fields, flat=False, named=False)

这类似于 values() 不同之处在于它在迭代时返回元组而不是返回字典。 每个元组包含来自传递到 values_list() 调用的相应字段或表达式的值——所以第一项是第一个字段,依此类推。 例如:

>>> Entry.objects.values_list('id', 'headline')
<QuerySet [(1, 'First entry'), ...]>
>>> from django.db.models.functions import Lower
>>> Entry.objects.values_list('id', Lower('headline'))
<QuerySet [(1, 'first entry'), ...]>

如果只传入单个字段,还可以传入 flat 参数。 如果 True,这将意味着返回的结果是单个值,而不是一元组。 一个例子应该能让区别更清楚:

>>> Entry.objects.values_list('id').order_by('id')
<QuerySet[(1,), (2,), (3,), ...]>

>>> Entry.objects.values_list('id', flat=True).order_by('id')
<QuerySet [1, 2, 3, ...]>

有多个字段时传入flat是错误的。

您可以通过 named=True 来获得作为 namedtuple() 的结果:

>>> Entry.objects.values_list('id', 'headline', named=True)
<QuerySet [Row(id=1, headline='First entry'), ...]>

使用命名元组可能会使使用结果更易读,但代价是将结果转化为命名元组时要付出很小的性能代价。

如果您没有将任何值传递给 values_list(),它将按照声明的顺序返回模型中的所有字段。

一个常见的需求是获取某个模型实例的特定字段值。 为此,请使用 values_list() 后跟 get() 调用:

>>> Entry.objects.values_list('headline', flat=True).get(pk=1)
'First entry'

values()values_list() 都是针对特定用例的优化:在没有创建模型实例的开销的情况下检索数据子集。 当处理多对多和其他多值关系(例如反向外键的一对多关系)时,这个比喻就失效了,因为“一行一个对象”假设不成立。

例如,请注意跨 ManyToManyField 查询时的行为:

>>> Author.objects.values_list('name', 'entry__headline')
<QuerySet [('Noam Chomsky', 'Impressions of Gaza'),
 ('George Orwell', 'Why Socialists Do Not Believe in Fun'),
 ('George Orwell', 'In Defence of English Cooking'),
 ('Don Quixote', None)]>

有多个条目的作者多次出现,没有任何条目的作者的条目标题为 None

同样,当查询反向外键时,对于没有任何作者的条目,会出现 None

>>> Entry.objects.values_list('authors')
<QuerySet [('Noam Chomsky',), ('George Orwell',), (None,)]>

dates()

dates(field, kind, order='ASC')

返回一个 QuerySet,其计算结果为 datetime.date 对象列表,表示 QuerySet 内容中特定类型的所有可用日期。

field 应该是您模型的 DateField 的名称。 kind 应为 "year""month""week""day"。 结果列表中的每个 datetime.date 对象都被“截断”为给定的 type

  • "year" 返回字段的所有不同年份值的列表。
  • "month" 返回字段的所有不同年/月值的列表。
  • "week" 返回该字段所有不同年/周值的列表。 所有日期都将是星期一。
  • "day" 返回字段的所有不同年/月/日值的列表。

order,默认为 'ASC',应该是 'ASC''DESC'。 这指定了如何对结果进行排序。

例子:

>>> Entry.objects.dates('pub_date', 'year')
[datetime.date(2005, 1, 1)]
>>> Entry.objects.dates('pub_date', 'month')
[datetime.date(2005, 2, 1), datetime.date(2005, 3, 1)]
>>> Entry.objects.dates('pub_date', 'week')
[datetime.date(2005, 2, 14), datetime.date(2005, 3, 14)]
>>> Entry.objects.dates('pub_date', 'day')
[datetime.date(2005, 2, 20), datetime.date(2005, 3, 20)]
>>> Entry.objects.dates('pub_date', 'day', order='DESC')
[datetime.date(2005, 3, 20), datetime.date(2005, 2, 20)]
>>> Entry.objects.filter(headline__contains='Lennon').dates('pub_date', 'day')
[datetime.date(2005, 3, 20)]

2.1 版变更: 增加了“周”支持。


datetimes()

datetimes(field_name, kind, order='ASC', tzinfo=None)

返回一个 QuerySet,其计算结果为 datetime.datetime 对象列表,表示 QuerySet 内容中特定类型的所有可用日期。

field_name 应该是您模型的 DateTimeField 的名称。

kind 应为 "year""month""week""day""hour""minute" , 或 "second"。 结果列表中的每个 datetime.datetime 对象都被“截断”为给定的 type

order,默认为 'ASC',应该是 'ASC''DESC'。 这指定了如何对结果进行排序。

tzinfo 定义日期时间在截断之前转换到的时区。 实际上,根据使用的时区,给定的日期时间具有不同的表示形式。 此参数必须是 datetime.tzinfo 对象。 如果是 None,Django 使用 当前时区:setting:`USE_TZ`False 时无效。

2.1 版变更: 增加了“周”支持。


注解

此函数直接在数据库中执行时区转换。 因此,您的数据库必须能够解释 tzinfo.tzname(None) 的值。 这转化为以下要求:

  • SQLite:没有要求。 使用 pytz(安装 Django 时安装)在 Python 中执行转换。
  • PostgreSQL:无要求(参见 时区 )。
  • Oracle:无要求(请参阅 选择时区文件 )。
  • MySQL:使用 mysql_tzinfo_to_sql 加载时区表。


none()

none()

调用 none() 将创建一个永远不会返回任何对象的查询集,并且在访问结果时不会执行任何查询。 qs.none() 查询集是 EmptyQuerySet 的一个实例。

例子:

>>> Entry.objects.none()
<QuerySet []>
>>> from django.db.models.query import EmptyQuerySet
>>> isinstance(Entry.objects.none(), EmptyQuerySet)
True

all()

all()

返回当前 QuerySet(或 QuerySet 子类)的 副本 。 这在您可能希望传入模型管理器或 QuerySet 并对结果进行进一步过滤的情况下非常有用。 在任一对象上调用 all() 之后,您肯定会有一个 QuerySet 可以使用。

QuerySet评估 时,它通常会缓存其结果。 如果自评估 QuerySet 后数据库中的数据可能已更改,您可以通过对先前评估的 QuerySet 调用 all() 来获取同一查询的更新结果。


union()

union(*other_qs, all=False)

使用 SQL 的 UNION 运算符组合两个或多个 QuerySet 的结果。 例如:

>>> qs1.union(qs2, qs3)

默认情况下,UNION 运算符仅选择不同的值。 要允许重复值,请使用 all=True 参数。

union()intersection()difference() 返回第一个 QuerySet 类型的模型实例,即使参数是其他的 QuerySet楷模。 只要 SELECT 列表在所有 QuerySet 中都相同(至少是类型,名称无关紧要,只要类型的顺序相同)就可以传递不同的模型。 在这种情况下,您必须使用应用到结果 QuerySetQuerySet 方法中第一个 QuerySet 的列名。 例如:

>>> qs1 = Author.objects.values_list('name')
>>> qs2 = Entry.objects.values_list('headline')
>>> qs1.union(qs2).order_by('name')

此外,只有 LIMITOFFSETCOUNT(*)ORDER BY,并指定列(即 切片,count()order_by()values()/values_list()) 允许在结果 [X123X ]。 此外,数据库对组合查询中允许的操作进行了限制。 例如,大多数数据库不允许在组合查询中使用 LIMITOFFSET


intersection()

intersection(*other_qs)

使用 SQL 的 INTERSECT 运算符返回两个或多个 QuerySet 的共享元素。 例如:

>>> qs1.intersection(qs2, qs3)

有关一些限制,请参阅 union()


difference()

difference(*other_qs)

使用 SQL 的 EXCEPT 运算符仅保留 QuerySet 中存在的元素,而不保留其他一些 QuerySet 中的元素。 例如:

>>> qs1.difference(qs2, qs3)

有关一些限制,请参阅 union()


extra()

extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None)

有时,Django 查询语法本身无法轻松表达复杂的 WHERE 子句。 对于这些边缘情况,Django 提供了 extra() QuerySet 修饰符——一个钩子,用于将特定子句注入由 QuerySet 生成的 SQL。

在万不得已的情况下使用这种方法

这是一个旧的 API,我们的目标是在未来的某个时候弃用。 仅当您无法使用其他查询集方法表达查询时才使用它。 如果您确实需要使用它,请使用 QuerySet.extra 关键字 与您的用例一起 提交票证 (请先检查现有票证列表),以便我们可以增强QuerySet API 允许删除 extra()。 我们不再改进或修复此方法的错误。

例如,extra() 的这种用法:

>>> qs.extra(
...     select={'val': "select col from sometable where othercol = %s"},
...     select_params=(someparam,),
... )

相当于:

>>> qs.annotate(val=RawSQL("select col from sometable where othercol = %s", (someparam,)))

使用 RawSQL 的主要好处是您可以根据需要设置 output_field。 主要的缺点是,如果您在原始 SQL 中引用查询集的某个表别名,那么 Django 可能会更改该别名(例如,当查询集用作另一个查询中的子查询时)。


警告

使用 extra() 时应该非常小心。 每次使用它时,都应该使用 params 对用户可以控制的任何参数进行转义,以防止 SQL 注入攻击。

您也不得在 SQL 字符串中引用占位符。 由于 %s 周围的引号,此示例容易受到 SQL 注入攻击:

"select col from sometable where othercol = '%s'"  # unsafe!

您可以阅读有关 Django SQL 注入保护 工作原理的更多信息。


根据定义,这些额外的查找可能无法移植到不同的数据库引擎(因为您明确地编写 SQL 代码)并且违反了 DRY 原则,因此您应该尽可能避免它们。

指定 paramsselectwheretables 中的一个或多个。 不需要任何参数,但您应该至少使用其中之一。

  • select

    select 参数允许您在 SELECT 子句中放置额外的字段。 它应该是一个将属性名称映射到 SQL 子句以用于计算该属性的字典。

    例子:

    Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})

    因此,每个 Entry 对象都会有一个额外的属性 is_recent,这是一个布尔值,表示条目的 pub_date 是否大于 Jan。 1, 2006.

    Django 将给定的 SQL 片段直接插入到 SELECT 语句中,因此上述示例的结果 SQL 将类似于:

    SELECT blog_entry.*, (pub_date > '2006-01-01') AS is_recent
    FROM blog_entry;

    下一个例子更高级; 它执行一个子查询,为每个结果 Blog 对象提供一个 entry_count 属性,关联 Entry 对象的整数计数:

    Blog.objects.extra(
        select={
            'entry_count': 'SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id'
        },
    )

    在这种特殊情况下,我们利用查询已经在其 FROM 子句中包含 blog_blog 表的事实。

    上述示例的结果 SQL 将是:

    SELECT blog_blog.*, (SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id) AS entry_count
    FROM blog_blog;

    请注意,在 Django 的 select 子句中,大多数数据库引擎所需的围绕子查询的括号不是必需的。 另请注意,某些数据库后端(例如某些 MySQL 版本)不支持子查询。

    在极少数情况下,您可能希望将参数传递给 extra(select=...) 中的 SQL 片段。 为此,请使用 select_params 参数。 由于 select_params 是一个序列,而 select 属性是一个字典,因此需要小心谨慎,以便参数与额外的选择片段正确匹配。 在这种情况下,您应该对 select 值使用 collections.OrderedDict,而不仅仅是普通的 Python 字典。

    这将起作用,例如:

    Blog.objects.extra(
        select=OrderedDict([('a', '%s'), ('b', '%s')]),
        select_params=('one', 'two'))

    如果需要在选择字符串中使用文字 %s,请使用序列 %%s

  • where / tables

    您可以使用 where 定义显式 SQL WHERE 子句——也许是为了执行非显式连接。 您可以使用 tables 手动向 SQL FROM 子句添加表。

    wheretables 都采用字符串列表。 所有 where 参数都与任何其他搜索条件进行“与”运算。

    例子:

    Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])

    ...翻译(大致)为以下 SQL:

    SELECT * FROM blog_entry WHERE (foo='a' OR bar='a') AND (baz='a')

    如果您指定的表已在查询中使用,则在使用 tables 参数时要小心。 当您通过 tables 参数添加额外的表时,Django 假定您希望该表包含额外的时间,如果它已经包含在内。 这就产生了一个问题,因为表名将被赋予一个别名。 如果一个表在 SQL 语句中多次出现,则第二次和后续出现必须使用别名,以便数据库可以区分它们。 如果您指的是在额外 where 参数中添加的额外表,这将导致错误。

    通常,您只会添加尚未出现在查询中的额外表。 但是,如果确实发生了上述情况,则有几种解决方案。 首先,看看您是否可以不包含额外的表并使用查询中已有的表。 如果这是不可能的,请将您的 extra() 调用放在查询集构造的前面,以便您的表是该表的第一次使用。 最后,如果所有其他方法都失败了,请查看生成的查询并重写您的 where 添加以使用为额外表提供的别名。 每次以相同的方式构造查询集时,别名都将相同,因此您可以依赖别名不会更改。

  • order_by

    如果您需要使用通过 extra() 包含的一些新字段或表对结果查询集进行排序,请使用 order_by 参数到 extra() 并传入一系列字符串。 这些字符串应该是模型字段(如查询集上的正常 order_by() 方法),形式为 table_name.column_name 或您在 [ 中指定的列的别名X181X] 参数设置为 extra()

    例如:

    q = Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})
    q = q.extra(order_by = ['-is_recent'])

    这会将 is_recent 为真的所有项目排序到结果集的前面(True 按降序排列在 False 之前)。

    顺便说一下,这表明您可以多次调用 extra() 并且它会按照您的预期运行(每次添加新约束)。

  • params

    上述 where 参数可以使用标准 Python 数据库字符串占位符 — '%s' 来指示数据库引擎应自动引用的参数。 params 参数是要替换的任何额外参数的列表。

    例子:

    Entry.objects.extra(where=['headline=%s'], params=['Lennon'])

    始终使用 params 而不是直接将值嵌入到 where 中,因为 params 将确保根据您的特定后端正确引用值。 例如,引号将被正确转义。

    坏的:

    Entry.objects.extra(where=["headline='Lennon'"])

    好的:

    Entry.objects.extra(where=['headline=%s'], params=['Lennon'])

警告

如果您在 MySQL 上执行查询,请注意 MySQL 的静默类型强制在混合类型时可能会导致意外结果。 如果查询字符串类型的列,但使用的是整数值,MySQL 会在执行比较之前将表中所有值的类型强制为整数。 例如,如果您的表包含值 'abc''def' 并且您查询 WHERE mycolumn=0,则两行都将匹配。 为防止出现这种情况,请在查询中使用该值之前执行正确的类型转换。


defer()

defer(*fields)

在某些复杂的数据建模情况下,您的模型可能包含大量字段,其中一些字段可能包含大量数据(例如,文本字段),或者需要进行昂贵的处理才能将它们转换为 Python 对象。 如果您在最初获取数据时不知道是否需要这些特定字段的情况下使用查询集的结果,您可以告诉 Django 不要从数据库中检索它们。

这是通过将字段的名称传递给 defer() 来完成的:

Entry.objects.defer("headline", "body")

具有延迟字段的查询集仍将返回模型实例。 如果您访问该字段(一次一个,而不是一次访问所有延迟字段),将从数据库中检索每个延迟字段。

您可以多次呼叫 defer()。 每次调用都会向延迟集合添加新字段:

# Defers both the body and headline fields.
Entry.objects.defer("body").filter(rating=5).defer("headline")

将字段添加到延迟集中的顺序无关紧要。 使用已被延迟的字段名称调用 defer() 是无害的(该字段仍将被延迟)。

您可以通过使用标准双下划线符号分隔相关字段来延迟加载相关模型中的字段(如果相关模型通过 select_related() 加载):

Blog.objects.select_related().defer("entry__headline", "entry__body")

如果要清除延迟字段集,请将 None 作为参数传递给 defer()

# Load all fields immediately.
my_queryset.defer(None)

模型中的某些字段不会被延迟,即使您要求它们。 你永远不能推迟主键的加载。 如果您使用 select_related() 检索相关模型,则不应推迟从主模型连接到相关模型的字段的加载,否则会导致错误。

注解

defer() 方法(及其表亲 only(),如下)仅适用于高级用例。 当您仔细分析查询并准确了解 ' 您需要什么信息并测量返回您需要的字段与模型的完整字段集之间的差异时,它们提供了一种优化。

即使您认为您处于高级用例情况, 仅在您无法在查询集加载时确定是否需要额外字段时才使用 defer() 。 如果您经常加载和使用数据的特定子集,您可以做出的最佳选择是规范化模型并将未加载的数据放入单独的模型(和数据库表)中。 如果列 must 出于某种原因保留在一个表中,请使用 Meta.managed = False 创建一个模型(请参阅 managed 属性 文档)只包含您通常需要的字段加载并使用您可能会调用 defer() 的地方。 这使您的代码对读者更加明确,速度稍快,并且在 Python 进程中消耗的内存更少。

例如,这两个模型都使用相同的底层数据库表:

class CommonlyUsedModel(models.Model):
    f1 = models.CharField(max_length=10)

    class Meta:
        managed = False
        db_table = 'app_largetable'

class ManagedModel(models.Model):
    f1 = models.CharField(max_length=10)
    f2 = models.CharField(max_length=10)

    class Meta:
        db_table = 'app_largetable'

# Two equivalent QuerySets:
CommonlyUsedModel.objects.all()
ManagedModel.objects.all().defer('f2')

如果很多字段需要在非托管模型中重复,最好的办法是创建一个共享字段的抽象模型,然后让非托管模型和托管模型从抽象模型中继承。


注解

当为具有延迟字段的实例调用 save() 时,只会保存加载的字段。 有关更多详细信息,请参阅 save()


only()

only(*fields)

only() 方法或多或少与 defer() 相反。 您可以使用在检索模型时应延迟 而非 的字段调用它。 如果您的模型几乎所有字段都需要延迟,则使用 only() 指定补充字段集可以简化代码。

假设您有一个包含字段 nameagebiography 的模型。 以下两个查询集在延迟字段方面是相同的:

Person.objects.defer("age", "biography")
Person.objects.only("name")

每当您调用 only() 时,它会 替换 立即加载的字段集。 该方法的名称是助记符:only 那些字段会立即加载; 其余的被推迟。 因此,对 only() 的连续调用导致只考虑最终字段:

# This will defer all fields except the headline.
Entry.objects.only("body", "rating").only("headline")

由于 defer() 以增量方式起作用(将字段添加到延迟列表中),您可以组合对 only()defer() 的调用,并且事情将按逻辑进行:

# Final result is that everything except "headline" is deferred.
Entry.objects.only("headline", "body").defer("body")

# Final result loads headline and body immediately (only() replaces any
# existing set of fields).
Entry.objects.defer("body").only("headline", "body")

defer() 文档注释中的所有注意事项也适用于 only()。 谨慎使用它,并且只有在用尽你的其他选择之后。

使用 only() 并省略使用 select_related() 请求的字段也是一个错误。

注解

当为具有延迟字段的实例调用 save() 时,只会保存加载的字段。 有关更多详细信息,请参阅 save()


using()

using(alias)

如果您使用多个数据库,此方法用于控制 QuerySet 将针对哪个数据库进行评估。 此方法采用的唯一参数是数据库的别名,如 :setting:`DATABASES` 中所定义。

例如:

# queries the database with the 'default' alias.
>>> Entry.objects.all()

# queries the database with the 'backup' alias
>>> Entry.objects.using('backup')

select_for_update()

select_for_update(nowait=False, skip_locked=False, of=())

返回将锁定行直到事务结束的查询集,在支持的数据库上生成 SELECT ... FOR UPDATE SQL 语句。

例如:

from django.db import transaction

entries = Entry.objects.select_for_update().filter(author=request.user)
with transaction.atomic():
    for entry in entries:
        ...

当查询集被评估时(在本例中为 for entry in entries),所有匹配的条目将被锁定,直到事务块结束,这意味着将阻止其他事务更改或获取对它们的锁。

通常,如果另一个事务已经获得了对选定行之一的锁定,则查询将阻塞,直到锁定被释放。 如果这不是您想要的行为,请调用 select_for_update(nowait=True)。 这将使调用非阻塞。 如果另一个事务已经获取了冲突锁,则在评估查询集时将引发 DatabaseError。 您也可以使用 select_for_update(skip_locked=True) 来忽略锁定的行。 nowaitskip_locked 是互斥的,在启用这两个选项的情况下尝试调用 select_for_update() 将导致 ValueError

默认情况下,select_for_update() 锁定查询选择的所有行。 例如,除了查询集模型的行之外,select_related() 中指定的相关对象的行也被锁定。 如果不需要,请使用与 select_related() 相同的字段语法在 select_for_update(of=(...)) 中指定要锁定的相关对象。 使用值 'self' 来引用查询集的模型。

select_for_update(of=(...)) 中锁定父母模型

如果要在使用 多表继承 时锁定父模型,则必须在 of 参数中指定父链接字段(默认为 <parent_model_name>_ptr)。 例如:

Restaurant.objects.select_for_update(of=('self', 'place_ptr'))

您不能在可空关系上使用 select_for_update()

>>> Person.objects.select_related('hometown').select_for_update()
Traceback (most recent call last):
...
django.db.utils.NotSupportedError: FOR UPDATE cannot be applied to the nullable side of an outer join

为了避免这种限制,如果您不关心它们,您可以排除空对象:

>>> Person.objects.select_related('hometown').select_for_update().exclude(hometown=None)
<QuerySet [<Person: ...)>, ...]>

目前,postgresqloraclemysql 数据库后端支持 select_for_update()。 但是,MySQL 不支持 [X35X] 参数,并且仅在 MySQL 8.0.1+ 上支持 nowaitskip_locked 参数。

使用不支持这些选项的数据库后端(例如 MySQL)将 nowait=Trueskip_locked=Trueof 传递给 select_for_update(),会引发 NotSupportedError[ X160X]。 这可以防止代码意外阻塞。

在支持 SELECT ... FOR UPDATE 的后端在自动提交模式下使用 select_for_update() 评估查询集是一个 TransactionManagementError 错误,因为在这种情况下行未锁定。 如果允许,这将促进数据损坏,并且很容易由调用预期在事务之外的事务中运行的代码引起。

在不支持 SELECT ... FOR UPDATE 的后端(例如 SQLite)上使用 select_for_update() 将不起作用。 SELECT ... FOR UPDATE 不会添加到查询中,如果在自动提交模式下使用 select_for_update(),则不会引发错误。

警告

尽管 select_for_update() 在自动提交模式下通常会失败,但由于 TestCase 自动将每个测试包装在一个事务中,即使在 之外调用 TestCase 中的 select_for_update() atomic() 块将(可能出乎意料地)通过而不引发 TransactionManagementError。 要正确测试 select_for_update(),您应该使用 TransactionTestCase


可能不支持某些表达方式

PostgreSQL 不支持 select_for_update()Window 表达式。


raw()

raw(raw_query, params=None, translations=None)

获取原始 SQL 查询,执行它,并返回一个 django.db.models.query.RawQuerySet 实例。 这个 RawQuerySet 实例可以像普通的 QuerySet 一样迭代以提供对象实例。

有关详细信息,请参阅 执行原始 SQL 查询

警告

raw() 总是触发一个新的查询并且不考虑之前的过滤。 因此,通常应该从 Manager 或新的 QuerySet 实例调用它。


返回新 QuerySet 的运算符

组合的查询集必须使用相同的模型。

与 (&)

使用 SQL AND 运算符组合两个 QuerySet

以下是等效的:

Model.objects.filter(x=1) & Model.objects.filter(y=2)
Model.objects.filter(x=1, y=2)
from django.db.models import Q
Model.objects.filter(Q(x=1) & Q(y=2))

SQL 等价于:

SELECT ... WHERE x=1 AND y=2

或 (|)

使用 SQL OR 运算符组合两个 QuerySet

以下是等效的:

Model.objects.filter(x=1) | Model.objects.filter(y=2)
from django.db.models import Q
Model.objects.filter(Q(x=1) | Q(y=2))

SQL 等价于:

SELECT ... WHERE x=1 OR y=2

不返回 QuerySets 的方法

以下 QuerySet 方法评估 QuerySet 并返回 以外的QuerySet

这些方法不使用缓存(参见 Caching 和 QuerySets)。 相反,他们每次被调用时都会查询数据库。

get()

get(**kwargs)

返回与给定查找参数匹配的对象,该对象应采用 字段查找 中描述的格式。

get() 如果找到多个对象,则引发 MultipleObjectsReturnedMultipleObjectsReturned 异常是模型类的一个属性。

get() 如果未找到给定参数的对象,则会引发 DoesNotExist 异常。 这个异常是模型类的一个属性。 例子:

Entry.objects.get(id='foo') # raises Entry.DoesNotExist

DoesNotExist 异常继承自 django.core.exceptions.ObjectDoesNotExist,因此您可以针对多个 DoesNotExist 异常。 例子:

from django.core.exceptions import ObjectDoesNotExist
try:
    e = Entry.objects.get(id=3)
    b = Blog.objects.get(id=1)
except ObjectDoesNotExist:
    print("Either the entry or blog doesn't exist.")

如果您希望查询集返回一行,则可以使用不带任何参数的 get() 来返回该行的对象:

entry = Entry.objects.filter(...).exclude(...).get()

create()

create(**kwargs)

一种创建对象并将其全部保存在一个步骤中的便捷方法。 因此:

p = Person.objects.create(first_name="Bruce", last_name="Springsteen")

和:

p = Person(first_name="Bruce", last_name="Springsteen")
p.save(force_insert=True)

是等效的。

force_insert 参数在别处有说明,但这意味着总是会创建一个新对象。 通常你不需要担心这个。 但是,如果您的模型包含您设置的手动主键值,并且该值已存在于数据库中,则调用 create() 将失败并显示 IntegrityError,因为主键必须是唯一的. 如果您使用手动主键,请准备好处理异常。


get_or_create()

get_or_create(defaults=None, **kwargs)

一种使用给定 kwargs 查找对象的便捷方法(如果您的模型具有所有字段的默认值,则可能为空),如有必要,创建一个。

返回 (object, created) 的元组,其中 object 是检索或创建的对象,created 是指定是否创建新对象的布尔值。

这是为了防止在并行发出请求时创建重复的对象,并作为样板代码的快捷方式。 例如:

try:
    obj = Person.objects.get(first_name='John', last_name='Lennon')
except Person.DoesNotExist:
    obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
    obj.save()

这里,对于并发请求,可能会多次尝试保存具有相同参数的 Person。 为了避免这种竞争条件,上面的例子可以使用 get_or_create() 重写,如下所示:

obj, created = Person.objects.get_or_create(
    first_name='John',
    last_name='Lennon',
    defaults={'birthday': date(1940, 10, 9)},
)

任何传递给 get_or_create() 的关键字参数 — 除外 一个称为 defaults 的可选参数 — 将在 get() 调用中使用。 如果找到对象,get_or_create() 返回该对象的元组和 False

警告

此方法是原子的,假设数据库强制关键字参数的唯一性(请参阅 uniqueunique_together)。 如果关键字参数中使用的字段没有唯一性约束,则对此方法的并发调用可能会导致插入具有相同参数的多行。


您可以通过将 get_or_create()filter() 链接起来并使用 Q 对象 来为检索到的对象指定更复杂的条件。 例如,检索 Robert 或 Bob Marley(如果存在),否则创建后者:

from django.db.models import Q

obj, created = Person.objects.filter(
    Q(first_name='Bob') | Q(first_name='Robert'),
).get_or_create(last_name='Marley', defaults={'first_name': 'Bob'})

如果找到多个对象,get_or_create() 会引发 MultipleObjectsReturned。 如果没有找到一个对象,get_or_create()将实例化并保存一个新对象,返回一个新对象和True的元组。 新对象将根据以下算法大致创建:

params = {k: v for k, v in kwargs.items() if '__' not in k}
params.update({k: v() if callable(v) else v for k, v in defaults.items()})
obj = self.model(**params)
obj.save()

在英语中,这意味着以任何不包含双下划线的非 'defaults' 关键字参数开头(这表示不精确的查找)。 然后添加 defaults 的内容,必要时覆盖任何键,并将结果用作模型类的关键字参数。 如果 defaults 中有任何可调用对象,请评估它们。 如上所述,这是所用算法的简化,但它包含所有相关细节。 内部实现具有比这更多的错误检查并处理一些额外的边缘条件; 如果您有兴趣,请阅读代码。

如果您有一个名为 defaults 的字段并希望将其用作 get_or_create() 中的精确查找,只需使用 'defaults__exact',如下所示:

Foo.objects.get_or_create(defaults__exact='bar', defaults={'defaults': 'baz'})

当您使用手动指定的主键时,get_or_create() 方法具有与 create() 类似的错误行为。 如果需要创建对象并且密钥已经存在于数据库中,则会引发 IntegrityError

最后,谈谈在 Django 视图中使用 get_or_create()。 请确保仅在 POST 请求中使用它,除非您有充分的理由不这样做。 GET 请求不应对数据产生任何影响。 相反,只要对页面的请求对您的数据有副作用,就使用 POST。 有关更多信息,请参阅 HTTP 规范中的 安全方法

警告

您可以使用 get_or_create()ManyToManyField 属性和反向关系。 在这种情况下,您将限制该关系上下文内的查询。 如果您不始终如一地使用它,这可能会导致您出现一些完整性问题。

有以下型号:

class Chapter(models.Model):
    title = models.CharField(max_length=255, unique=True)

class Book(models.Model):
    title = models.CharField(max_length=256)
    chapters = models.ManyToManyField(Chapter)

您可以通过 Book 的章节字段使用 get_or_create(),但它只能在该书的上下文中获取:

>>> book = Book.objects.create(title="Ulysses")
>>> book.chapters.get_or_create(title="Telemachus")
(<Chapter: Telemachus>, True)
>>> book.chapters.get_or_create(title="Telemachus")
(<Chapter: Telemachus>, False)
>>> Chapter.objects.create(title="Chapter 1")
<Chapter: Chapter 1>
>>> book.chapters.get_or_create(title="Chapter 1")
# Raises IntegrityError

之所以发生这种情况,是因为它试图通过“尤利西斯”一书获取或创建“第 1 章”,但它无法执行任何操作:该关系无法获取该章节,因为它与该书无关,但是它也不能创建它,因为 title 字段应该是唯一的。


update_or_create()

update_or_create(defaults=None, **kwargs)

一种使用给定 kwargs 更新对象的便捷方法,必要时创建一个新对象。 defaults 是用于更新对象的(字段,值)对的字典。 defaults 中的值可以是可调用的。

返回 (object, created) 元组,其中 object 是创建或更新的对象,created 是一个布尔值,指定是否创建了新对象。

update_or_create 方法尝试根据给定的 kwargs 从数据库中获取一个对象。 如果找到匹配项,它会更新 defaults 字典中传递的字段。

这意味着作为样板代码的快捷方式。 例如:

defaults = {'first_name': 'Bob'}
try:
    obj = Person.objects.get(first_name='John', last_name='Lennon')
    for key, value in defaults.items():
        setattr(obj, key, value)
    obj.save()
except Person.DoesNotExist:
    new_values = {'first_name': 'John', 'last_name': 'Lennon'}
    new_values.update(defaults)
    obj = Person(**new_values)
    obj.save()

随着模型中字段数量的增加,这种模式变得非常笨拙。 上面的例子可以使用 update_or_create() 重写,如下所示:

obj, created = Person.objects.update_or_create(
    first_name='John', last_name='Lennon',
    defaults={'first_name': 'Bob'},
)

有关如何解析 kwargs 中传递的名称的详细说明,请参阅 get_or_create()

如上文 get_or_create() 中所述,此方法容易出现竞争条件,如果未在数据库级别强制执行唯一性,则可能导致同时插入多行。

get_or_create()create(),如果您使用手动指定的主键并且需要创建一个对象但该键已经存在于数据库中,则 引发 IntegrityError


bulk_create()

bulk_create(objs, batch_size=None, ignore_conflicts=False)

此方法以高效的方式将提供的对象列表插入到数据库中(通常只有 1 个查询,无论有多少个对象):

>>> Entry.objects.bulk_create([
...     Entry(headline='This is a test'),
...     Entry(headline='This is only a test'),
... ])

不过这有一些注意事项:

  • 不会调用模型的save()方法,也不会发送pre_savepost_save信号。

  • 在多表继承的情况下,它不能与子模型一起工作。

  • 如果模型的主键是 AutoField,它不会像 save() 那样检索和设置主键属性,除非数据库后端支持它(当前是 PostgreSQL)。

  • 对于多对多的关系,它是行不通的。

  • 它将 objs 转换为一个列表,如果它是一个生成器,它会完全评估 objs。 强制转换允许检查所有对象,以便可以首先插入具有手动设置的主键的任何对象。 如果您想批量插入对象而不一次评估整个生成器,只要对象没有任何手动设置的主键,您就可以使用此技术:

    from itertools import islice
    
    batch_size = 100
    objs = (Entry(headline='Test %s' % i) for i in range(1000))
    while True:
        batch = list(islice(objs, batch_size))
        if not batch:
            break
        Entry.objects.bulk_create(batch, batch_size)

batch_size 参数控制在单个查询中创建的对象数量。 默认是批量创建所有对象,SQLite 除外,默认情况下每个查询最多使用 999 个变量。

在支持它的数据库上(除了 PostgreSQL < 9.5 和 Oracle),设置ignore_conflicts参数为True告诉数据库忽略插入失败约束(例如重复唯一值)的任何行的失败。 启用此参数将禁用在每个模型实例上设置主键(如果数据库通常支持它)。

2.2 版更改: 添加了 ignore_conflicts 参数。


bulk_update()

2.2 版中的新功能。


bulk_update(objs, fields, batch_size=None)

此方法有效地更新提供的模型实例上的给定字段,通常使用一个查询:

>>> objs = [
...    Entry.objects.create(headline='Entry 1'),
...    Entry.objects.create(headline='Entry 2'),
... ]
>>> objs[0].headline = 'This is entry 1'
>>> objs[1].headline = 'This is entry 2'
>>> Entry.objects.bulk_update(objs, ['headline'])

QuerySet.update() 用于保存更改,因此这比遍历模型列表并在每个模型上调用 save() 更有效,但它有一些警告:

  • 您无法更新模型的主键。
  • 不会调用每个模型的 save() 方法,并且不会发送 pre_savepost_save 信号。
  • 如果更新大量行中的大量列,则生成的 SQL 可能非常大。 通过指定合适的 batch_size 来避免这种情况。
  • 更新定义在多表继承祖先上的字段将给每个祖先带来额外的查询。
  • 如果 objs 包含重复项,则仅更新第一个。

batch_size 参数控制在单个查询中保存的对象数量。 默认是批量更新所有对象,SQLite 和 Oracle 除外,它们对查询中使用的变量数量有限制。


count()

count()

返回一个整数,表示数据库中与 QuerySet 匹配的对象数。

例子:

# Returns the total number of entries in the database.
Entry.objects.count()

# Returns the number of entries whose headline contains 'Lennon'
Entry.objects.filter(headline__contains='Lennon').count()

count() 调用在幕后执行 SELECT COUNT(*),因此您应该始终使用 count(),而不是将所有记录加载到 Python 对象中并调用 len()结果(除非您无论如何都需要将对象加载到内存中,在这种情况下 len() 会更快)。

请注意,如果您想要 QuerySet 中的项目数并且还从中检索模型实例(例如,通过对其进行迭代),则使用 len(queryset) 可能更有效t 会导致像 count() 这样的额外数据库查询。


in_bulk()

in_bulk(id_list=None, field_name='pk')

获取字段值列表 (id_list) 和这些值的 field_name,并返回一个字典,将每个值映射到具有给定字段值的对象实例。 如果未提供 id_list,则返回查询集中的所有对象。 field_name 必须是唯一字段,默认为主键。

例子:

>>> Blog.objects.in_bulk([1])
{1: <Blog: Beatles Blog>}
>>> Blog.objects.in_bulk([1, 2])
{1: <Blog: Beatles Blog>, 2: <Blog: Cheddar Talk>}
>>> Blog.objects.in_bulk([])
{}
>>> Blog.objects.in_bulk()
{1: <Blog: Beatles Blog>, 2: <Blog: Cheddar Talk>, 3: <Blog: Django Weblog>}
>>> Blog.objects.in_bulk(['beatles_blog'], field_name='slug')
{'beatles_blog': <Blog: Beatles Blog>}

如果你传递 in_bulk() 一个空列表,你会得到一个空字典。


iterator()

iterator(chunk_size=2000)

评估 QuerySet(通过执行查询)并返回一个迭代器(参见 PEP 234)。 QuerySet 通常在内部缓存其结果,以便重复评估不会导致额外的查询。 相比之下, iterator() 会直接读取结果,不会在 QuerySet 级别做任何缓存(在内部,默认迭代器调用 iterator() 并缓存返回值)。 对于返回大量只需要访问一次的对象的 QuerySet,这可以带来更好的性能并显着减少内存。

请注意,在已经计算过的 QuerySet 上使用 iterator() 将强制它再次计算,重复查询。

此外,使用 iterator() 会导致之前的 prefetch_related() 调用被忽略,因为这两个优化一起使用没有意义。

根据数据库后端,查询结果将被一次性加载或使用服务器端的游标从数据库中流转。

使用服务器端游标

Oracle 和 PostgreSQL 使用服务器端游标从数据库中流式传输结果,而无需将整个结果集加载到内存中。

Oracle 数据库驱动程序总是使用服务器端的游标。

对于服务器端游标,chunk_size 参数指定要在数据库驱动程序级别缓存的结果数。 获取更大的块会减少数据库驱动程序和数据库之间的往返次数,但会消耗内存。

在 PostgreSQL 上,服务器端游标只会在以下情况下使用 :设置:`DISABLE_SERVER_SIDE_CURSORS ` 设置是False . 如果您使用以事务池模式配置的连接池,请阅读 事务池和服务器端游标 。 禁用服务器端游标时,行为与不支持服务器端游标的数据库相同。


没有服务器端游标

MySQL 不支持流式结果,因此 Python 数据库驱动程序将整个结果集加载到内存中。 然后,数据库适配器使用 PEP 249 中定义的 fetchmany() 方法将结果集转换为 Python 行对象。

SQLite 可以使用 fetchmany() 批量获取结果,但由于 SQLite 不提供连接内查询之间的隔离,因此在写入被迭代的表时要小心。 有关详细信息,请参阅使用 QuerySet.iterator() 时的 隔离。

chunk_size 参数控制 Django 从数据库驱动程序中检索的批次大小。 较大的批处理减少了与数据库驱动程序通信的开销,但代价是内存消耗略有增加。

chunk_size 的默认值,2000,来自 psycopg 邮件列表 上的 计算:

假设行数为 10-20 列,文字数据和数字数据混合,2000 要取不到 100KB 的数据,这似乎是一个很好的折中方案,在传输的行数和提前退出循环时丢弃的数据之间。


2.2 版更改: 添加了对 SQLite 上的结果流的支持。


latest()

latest(*fields)

根据给定的字段,返回表中最新的对象。

本示例根据 pub_date 字段返回表中最新的 Entry

Entry.objects.latest('pub_date')

您还可以根据多个字段选择最新的。 例如,当两个条目具有相同的 pub_date 时,选择 Entry 与最早的 expire_date

Entry.objects.latest('pub_date', '-expire_date')

'-expire_date'中的负号表示按降序expire_date进行排序。 由于latest()得到最后的结果,所以选择了expire_date最早的Entry

如果您模型的 Meta 指定 get_latest_by,则您可以省略 earliest()latest() 的任何参数。 默认情况下将使用 get_latest_by 中指定的字段。

get()earliest()latest() 引发 DoesNotExist 如果没有具有给定参数的对象。

请注意,earliest()latest() 的存在纯粹是为了方便和可读性。

earliest()latest() 可能返回具有空日期的实例。

由于排序委托给数据库,如果您使用不同的数据库,则允许空值的字段的结果可能会以不同的方式排序。 例如,PostgreSQL 和 MySQL 对空值进行排序,就好像它们高于非空值一样,而 SQLite 则相反。

您可能希望过滤掉空值:

Entry.objects.filter(pub_date__isnull=False).latest('pub_date')

earliest()

earliest(*fields)

除了方向改变外,其他方式与 latest() 类似。


first()

first()

返回查询集匹配的第一个对象,如果没有匹配的对象,则返回 None。 如果 QuerySet 没有定义排序,那么查询集会自动按主键排序。 这可能会影响聚合结果,如 与默认排序或 order_by() 的交互中所述。

例子:

p = Article.objects.order_by('title', 'pub_date').first()

注意 first() 是一个方便的方法,下面的代码示例相当于上面的例子:

try:
    p = Article.objects.order_by('title', 'pub_date')[0]
except IndexError:
    p = None

last()

last()

first() 一样工作,但返回查询集中的最后一个对象。


aggregate()

aggregate(*args, **kwargs)

返回在 QuerySet 上计算的聚合值(平均值、总和等)的字典。 aggregate() 的每个参数指定一个值,该值将包含在返回的字典中。

Django 提供的聚合函数在下面的 Aggregation Functions 中描述。 由于聚合也是 查询表达式 ,您可以将聚合与其他聚合或值组合以创建复杂的聚合。

使用关键字参数指定的聚合将使用关键字作为注释的名称。 匿名参数将根据聚合函数的名称和正在聚合的模型字段为它们生成一个名称。 复杂聚合不能使用匿名参数,必须将关键字参数指定为别名。

例如,当您处理博客条目时,您可能想知道贡献了博客条目的作者数量:

>>> from django.db.models import Count
>>> q = Blog.objects.aggregate(Count('entry'))
{'entry__count': 16}

通过使用关键字参数指定聚合函数,您可以控制返回的聚合值的名称:

>>> q = Blog.objects.aggregate(number_of_entries=Count('entry'))
{'number_of_entries': 16}

有关聚合的深入讨论,请参阅 有关聚合的主题指南


exists()

exists()

如果 QuerySet 包含任何结果,则返回 True,否则返回 False。 这试图以最简单和最快的方式执行查询,但它 确实 执行与普通 QuerySet 查询几乎相同的查询。

exists() 可用于与 QuerySet 中的对象成员资格和 QuerySet 中任何对象的存在相关的搜索,特别是在大 查询集

查找模型是否具有唯一字段的最有效方法(例如 primary_key) 是 QuerySet 的成员是:

entry = Entry.objects.get(pk=123)
if some_queryset.filter(pk=entry.pk).exists():
    print("Entry contained in queryset")

这将比以下需要评估和迭代整个查询集的更快:

if entry in some_queryset:
   print("Entry contained in QuerySet")

并查找查询集是否包含任何项目:

if some_queryset.exists():
    print("There is at least one object in some_queryset")

这将比:

if some_queryset:
    print("There is at least one object in some_queryset")

……但不是很大(因此需要一个大的查询集来提高效率)。

此外,如果 some_queryset 尚未被评估,但您知道它会在某个时刻被评估,那么使用 some_queryset.exists() 将完成更多的整体工作(一个存在检查的查询加上一个额外的一到稍后检索结果),而不是简单地使用 bool(some_queryset),后者检索结果,然后检查是否有任何返回。


update()

update(**kwargs)

对指定的字段执行 SQL 更新查询,并返回匹配的行数(如果有些行已经有了新的值,则可能不等于更新的行数)。

例如,要关闭 2010 年发布的所有博客条目的评论,您可以执行以下操作:

>>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False)

(这假设您的 Entry 模型具有字段 pub_datecomments_on。)

您可以更新多个字段 - 数量没有限制。 例如,这里我们更新 comments_onheadline 字段:

>>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False, headline='This is old')

update() 方法是即时应用的,更新的 QuerySet 唯一的限制是它只能更新模型主表中的列,不能更新相关模型。 你不能这样做,例如:

>>> Entry.objects.update(blog__name='foo') # Won't work!

不过,仍然可以根据相关字段进行过滤:

>>> Entry.objects.filter(blog__id=1).update(comments_on=True)

您不能在已获取切片或无法再过滤的 QuerySet 上调用 update()

update() 方法返回受影响的行数:

>>> Entry.objects.filter(id=64).update(comments_on=True)
1

>>> Entry.objects.filter(slug='nonexistent-slug').update(comments_on=True)
0

>>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False)
132

如果你只是更新一条记录并且不需要对模型对象做任何事情,最有效的方法是调用 update(),而不是将模型对象加载到内存中。 例如,不要这样做:

e = Entry.objects.get(id=10)
e.comments_on = False
e.save()

…做这个:

Entry.objects.filter(id=10).update(comments_on=False)

使用 update() 还可以防止竞争条件,即在加载对象和调用 save() 之间的短时间内,数据库中的某些内容可能会发生变化。

最后,意识到 update() 在 SQL 级别进行更新,因此不会在您的模型上调用任何 save() 方法,也不会发出 pre_save 或 [ X169X]post_save 信号(这是调用 Model.save() 的结果)。 如果要更新具有自定义 save() 方法的模型的一堆记录,请遍历它们并调用 save(),如下所示:

for e in Entry.objects.filter(pub_date__year=2010):
    e.comments_on = False
    e.save()

delete()

delete()

QuerySet 中的所有行执行 SQL 删除查询,并返回删除的对象数和包含每种对象类型删除数的字典。

delete() 立即应用。 您不能在已获取切片或无法再过滤的 QuerySet 上调用 delete()

例如,要删除特定博客中的所有条目:

>>> b = Blog.objects.get(pk=1)

# Delete all the entries belonging to this Blog.
>>> Entry.objects.filter(blog=b).delete()
(4, {'weblog.Entry': 2, 'weblog.Entry_authors': 2})

默认情况下,Django 的 ForeignKey 模拟 SQL 约束 ON DELETE CASCADE — 换句话说,任何外键指向要删除的对象的对象都将被删除。 例如:

>>> blogs = Blog.objects.all()

# This will delete all Blogs and all of their Entry objects.
>>> blogs.delete()
(5, {'weblog.Blog': 1, 'weblog.Entry': 2, 'weblog.Entry_authors': 2})

此级联行为可通过 ForeignKeyon_delete 参数进行自定义。

delete() 方法执行批量删除,并且不会在您的模型上调用任何 delete() 方法。 但是,它确实为所有已删除的对象(包括级联删除)发出 pre_deletepost_delete 信号。

Django 需要将对象提取到内存中以发送信号和处理级联。 但是,如果没有级联和信号,那么 Django 可能会采用快速路径并删除对象而不提取到内存中。 对于大型删除,这会导致显着减少内存使用。 执行查询的数量也可以减少。

设置为 on_delete DO_NOTHING 的外键不会阻止在删除时采用快速路径。

需要注意的是,对象删除中产生的查询是一个实现细节,可能会发生变化。


as_manager()

classmethod as_manager()

返回 Manager 实例和 QuerySet 方法副本的类方法。 有关更多详细信息,请参阅 使用 QuerySet 方法创建管理器


explain()

2.1 版中的新功能。


explain(format=None, **options)

返回 QuerySet 的执行计划的字符串,它详细说明了数据库将如何执行查询,包括将使用的任何索引或连接。 了解这些细节可能会帮助您提高慢查询的性能。

例如,当使用 PostgreSQL 时:

>>> print(Blog.objects.filter(title='My Blog').explain())
Seq Scan on blog  (cost=0.00..35.50 rows=10 width=12)
  Filter: (title = 'My Blog'::bpchar)

不同数据库之间的输出有很大的不同。

explain() 被除 Oracle 之外的所有内置数据库后端支持,因为那里的实现并不简单。

format 参数改变了数据库默认的输出格式,通常是基于文本的。 PostgreSQL 支持 'TEXT''JSON''YAML''XML'。 MySQL 支持 'TEXT'(也称为 'TRADITIONAL')和 'JSON'

某些数据库接受可以返回有关查询的更多信息的标志。 将这些标志作为关键字参数传递。 例如,当使用 PostgreSQL 时:

>>> print(Blog.objects.filter(title='My Blog').explain(verbose=True))
Seq Scan on public.blog  (cost=0.00..35.50 rows=10 width=12) (actual time=0.004..0.004 rows=10 loops=1)
  Output: id, title
  Filter: (blog.title = 'My Blog'::bpchar)
Planning time: 0.064 ms
Execution time: 0.058 ms

在某些数据库上,标志可能会导致执行查询,这可能会对您的数据库产生不利影响。 例如,如果有触发器或函数被调用,PostgreSQL 的 ANALYZE 标志可能会导致数据更改,即使对于 SELECT 查询也是如此。


Field 查找

字段查找是您指定 SQL WHERE 子句内容的方式。 它们被指定为 QuerySet 方法 filter()exclude()get() 的关键字参数。

有关介绍,请参阅 模型和数据库查询文档

下面列出了 Django 的内置查找。 也可以为模型字段编写 自定义查找

为了方便,当没有提供查找类型时(如 Entry.objects.get(id=14)),查找类型假定为 :lookup:`exact`

exact

完全符合。 如果为比较提供的值是 None,它将被解释为 SQL NULL(有关更多详细信息,请参阅 :lookup:`isnull`)。

例子:

Entry.objects.get(id__exact=14)
Entry.objects.get(id__exact=None)

SQL 等效项:

SELECT ... WHERE id = 14;
SELECT ... WHERE id IS NULL;

MySQL 比较

在 MySQL 中,数据库表的“排序规则”设置确定 exact 比较是否区分大小写。 这是一个数据库设置, 不是 一个 Django 设置。 可以将 MySQL 表配置为使用区分大小写的比较,但需要进行一些权衡。 有关这方面的更多信息,请参阅 数据库 文档中的 整理部分


iexact

不区分大小写的精确匹配。 如果为比较提供的值是 None,它将被解释为 SQL NULL(有关更多详细信息,请参阅 :lookup:`isnull`)。

例子:

Blog.objects.get(name__iexact='beatles blog')
Blog.objects.get(name__iexact=None)

SQL 等效项:

SELECT ... WHERE name ILIKE 'beatles blog';
SELECT ... WHERE name IS NULL;

请注意,第一个查询将匹配 'Beatles Blog''beatles blog''BeAtLes BLoG' 等。

SQLite 用户

使用 SQLite 后端和非 ASCII 字符串时,请记住有关字符串比较的 数据库注释 。 SQLite 不会对非 ASCII 字符串进行不区分大小写的匹配。


contains

区分大小写的包含测试。

例子:

Entry.objects.get(headline__contains='Lennon')

SQL 等价于:

SELECT ... WHERE headline LIKE '%Lennon%';

请注意,这将匹配标题 'Lennon honored today' 但不匹配 'lennon honored today'

SQLite 用户

SQLite 不支持区分大小写的 LIKE 语句; contains 的作用类似于 SQLite 的 icontains。 有关更多信息,请参阅 数据库注释


icontains

不区分大小写的包含测试。

例子:

Entry.objects.get(headline__icontains='Lennon')

SQL 等价于:

SELECT ... WHERE headline ILIKE '%Lennon%';

SQLite 用户

使用 SQLite 后端和非 ASCII 字符串时,请记住有关字符串比较的 数据库注释


in

在给定的迭代中; 通常是列表、元组或查询集。 这不是一个常见的用例,但接受字符串(可迭代)。

例子:

Entry.objects.filter(id__in=[1, 3, 4])
Entry.objects.filter(headline__in='abc')

SQL 等效项:

SELECT ... WHERE id IN (1, 3, 4);
SELECT ... WHERE headline IN ('a', 'b', 'c');

您还可以使用查询集来动态评估值列表,而不是提供文字值列表:

inner_qs = Blog.objects.filter(name__contains='Cheddar')
entries = Entry.objects.filter(blog__in=inner_qs)

此查询集将作为子选择语句进行评估:

SELECT ... WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE '%Cheddar%')

如果您将 values()values_list() 产生的 QuerySet 作为值传递给 __in 查找,则需要确保只提取一个字段结果。 例如,这将起作用(过滤博客名称):

inner_qs = Blog.objects.filter(name__contains='Ch').values('name')
entries = Entry.objects.filter(blog__name__in=inner_qs)

此示例将引发异常,因为内部查询试图提取两个字段值,其中只需要一个:

# Bad code! Will raise a TypeError.
inner_qs = Blog.objects.filter(name__contains='Ch').values('name', 'id')
entries = Entry.objects.filter(blog__name__in=inner_qs)

性能注意事项

谨慎使用嵌套查询并了解您的数据库服务器的性能特征(如果有疑问,请进行基准测试!)。 一些数据库后端,尤其是 MySQL,不能很好地优化嵌套查询。 在这些情况下,提取值列表然后将其传递到第二个查询中会更有效。 也就是说,执行两个查询而不是一个:

values = Blog.objects.filter(
        name__contains='Cheddar').values_list('pk', flat=True)
entries = Entry.objects.filter(blog__in=list(values))

请注意博客 QuerySet 周围的 list() 调用以强制执行第一个查询。 没有它,将执行嵌套查询,因为 QuerySets 是惰性的


gt

大于。

例子:

Entry.objects.filter(id__gt=4)

SQL 等价于:

SELECT ... WHERE id > 4;

gte

大于等于。


lt

小于。


lte

小于等于


startswith

区分大小写的开头为。

例子:

Entry.objects.filter(headline__startswith='Lennon')

SQL 等价于:

SELECT ... WHERE headline LIKE 'Lennon%';

SQLite 不支持区分大小写的 LIKE 语句; startswith 的作用类似于 SQLite 的 istartswith


istartswith

不区分大小写的开头为。

例子:

Entry.objects.filter(headline__istartswith='Lennon')

SQL 等价于:

SELECT ... WHERE headline ILIKE 'Lennon%';

SQLite 用户

使用 SQLite 后端和非 ASCII 字符串时,请记住有关字符串比较的 数据库注释


endswith

区分大小写的结尾为。

例子:

Entry.objects.filter(headline__endswith='Lennon')

SQL 等价于:

SELECT ... WHERE headline LIKE '%Lennon';

SQLite 用户

SQLite 不支持区分大小写的 LIKE 语句; endswith 的作用类似于 SQLite 的 iendswith。 有关更多信息,请参阅 数据库注释 文档。


iendswith

不区分大小写的结尾为。

例子:

Entry.objects.filter(headline__iendswith='Lennon')

SQL 等价于:

SELECT ... WHERE headline ILIKE '%Lennon'

SQLite 用户

使用 SQLite 后端和非 ASCII 字符串时,请记住有关字符串比较的 数据库注释


range

范围测试(含)。

例子:

import datetime
start_date = datetime.date(2005, 1, 1)
end_date = datetime.date(2005, 3, 31)
Entry.objects.filter(pub_date__range=(start_date, end_date))

SQL 等价于:

SELECT ... WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31';

在 SQL 中可以使用 BETWEEN 的任何地方都可以使用 range — 用于日期、数字甚至字符。

警告

用日期过滤 DateTimeField 将不包括最后一天的项目,因为边界被解释为“给定日期的上午 0 点”。 如果 pub_date 是一个 DateTimeField,上面的表达式会变成这个 SQL:

SELECT ... WHERE pub_date BETWEEN '2005-01-01 00:00:00' and '2005-03-31 00:00:00';

一般来说,您不能混合日期和日期时间。


date

对于日期时间字段,将值转换为日期。 允许链接额外的字段查找。 获取日期值。

例子:

Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))

(由于不同的数据库引擎对相关查询的实现各不相同,因此本次查询不包含等效的 SQL 代码片段)。

:setting:`USE_TZ`True 时,字段在过滤前转换为当前时区。 这需要数据库 中的 时区定义。


year

对于日期和日期时间字段,精确的年份匹配。 允许链接额外的字段查找。 取整数年。

例子:

Entry.objects.filter(pub_date__year=2005)
Entry.objects.filter(pub_date__year__gte=2005)

SQL 等价于:

SELECT ... WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31';
SELECT ... WHERE pub_date >= '2005-01-01';

(确切的 SQL 语法因每个数据库引擎而异)。

:setting:`USE_TZ`True 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 中的 时区定义。


iso_year

2.2 版中的新功能。


对于日期和日期时间字段,精确的 ISO 8601 周编号年份匹配。 允许链接额外的字段查找。 取整数年。

例子:

Entry.objects.filter(pub_date__iso_year=2005)
Entry.objects.filter(pub_date__iso_year__gte=2005)

(确切的 SQL 语法因每个数据库引擎而异)。

:setting:`USE_TZ`True 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 中的 时区定义。


month

对于日期和日期时间字段,精确的月份匹配。 允许链接额外的字段查找。 取整数 1(一月)到 12(十二月)。

例子:

Entry.objects.filter(pub_date__month=12)
Entry.objects.filter(pub_date__month__gte=6)

SQL 等价于:

SELECT ... WHERE EXTRACT('month' FROM pub_date) = '12';
SELECT ... WHERE EXTRACT('month' FROM pub_date) >= '6';

(确切的 SQL 语法因每个数据库引擎而异)。

:setting:`USE_TZ`True 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 中的 时区定义。


day

对于日期和日期时间字段,精确的日期匹配。 允许链接额外的字段查找。 需要整数天。

例子:

Entry.objects.filter(pub_date__day=3)
Entry.objects.filter(pub_date__day__gte=3)

SQL 等价于:

SELECT ... WHERE EXTRACT('day' FROM pub_date) = '3';
SELECT ... WHERE EXTRACT('day' FROM pub_date) >= '3';

(确切的 SQL 语法因每个数据库引擎而异)。

请注意,这将匹配任何带有 pub_date 的月份第三天的记录,如 1 月 3 日,7 月 3 日等。

:setting:`USE_TZ`True 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 中的 时区定义。


week

对于日期和日期时间字段,根据 ISO-8601 返回周数(1-52 或 53),即周从星期一开始,第一周包含年度的第一个星期四。

例子:

Entry.objects.filter(pub_date__week=52)
Entry.objects.filter(pub_date__week__gte=32, pub_date__week__lte=38)

(由于不同的数据库引擎对相关查询的实现各不相同,因此本次查询不包含等效的 SQL 代码片段)。

:setting:`USE_TZ`True 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 中的 时区定义。


week_day

对于日期和日期时间字段,“星期几”匹配。 允许链接额外的字段查找。

从 1(星期日)到 7(星期六)取一个整数值,代表一周的一天。

例子:

Entry.objects.filter(pub_date__week_day=2)
Entry.objects.filter(pub_date__week_day__gte=2)

(由于不同的数据库引擎对相关查询的实现各不相同,因此本次查询不包含等效的 SQL 代码片段)。

请注意,这将匹配任何具有 pub_date 位于星期一(一周的第 2 天)的记录,而不管它发生在哪个月份或年份。 工作日被索引,第 1 天是星期日,第 7 天是星期六。

:setting:`USE_TZ`True 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 中的 时区定义。


quarter

对于日期和日期时间字段,“一年中的一个季度”匹配。 允许链接额外的字段查找。 取一个 1 到 4 之间的整数值,表示一年中的一个季度。

检索第二季度(4 月 1 日至 6 月 30 日)条目的示例:

Entry.objects.filter(pub_date__quarter=2)

(由于不同的数据库引擎对相关查询的实现各不相同,因此本次查询不包含等效的 SQL 代码片段)。

:setting:`USE_TZ`True 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 中的 时区定义。


time

对于日期时间字段,将值转换为时间。 允许链接额外的字段查找。 采用 datetime.time 值。

例子:

Entry.objects.filter(pub_date__time=datetime.time(14, 30))
Entry.objects.filter(pub_date__time__range=(datetime.time(8), datetime.time(17)))

(由于不同的数据库引擎对相关查询的实现各不相同,因此本次查询不包含等效的 SQL 代码片段)。

:setting:`USE_TZ`True 时,字段在过滤前转换为当前时区。 这需要数据库 中的 时区定义。


hour

对于日期时间和时间字段,精确的小时匹配。 允许链接额外的字段查找。 取 0 到 23 之间的整数。

例子:

Event.objects.filter(timestamp__hour=23)
Event.objects.filter(time__hour=5)
Event.objects.filter(timestamp__hour__gte=12)

SQL 等价于:

SELECT ... WHERE EXTRACT('hour' FROM timestamp) = '23';
SELECT ... WHERE EXTRACT('hour' FROM time) = '5';
SELECT ... WHERE EXTRACT('hour' FROM timestamp) >= '12';

(确切的 SQL 语法因每个数据库引擎而异)。

:setting:`USE_TZ`True 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 中的 时区定义。


minute

对于日期时间和时间字段,精确的分钟匹配。 允许链接额外的字段查找。 取 0 到 59 之间的整数。

例子:

Event.objects.filter(timestamp__minute=29)
Event.objects.filter(time__minute=46)
Event.objects.filter(timestamp__minute__gte=29)

SQL 等价于:

SELECT ... WHERE EXTRACT('minute' FROM timestamp) = '29';
SELECT ... WHERE EXTRACT('minute' FROM time) = '46';
SELECT ... WHERE EXTRACT('minute' FROM timestamp) >= '29';

(确切的 SQL 语法因每个数据库引擎而异)。

:setting:`USE_TZ`True 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 中的 时区定义。


second

对于日期时间和时间字段,精确的第二个匹配。 允许链接额外的字段查找。 取 0 到 59 之间的整数。

例子:

Event.objects.filter(timestamp__second=31)
Event.objects.filter(time__second=2)
Event.objects.filter(timestamp__second__gte=31)

SQL 等价于:

SELECT ... WHERE EXTRACT('second' FROM timestamp) = '31';
SELECT ... WHERE EXTRACT('second' FROM time) = '2';
SELECT ... WHERE EXTRACT('second' FROM timestamp) >= '31';

(确切的 SQL 语法因每个数据库引擎而异)。

:setting:`USE_TZ`True 时,日期时间字段在过滤前转换为当前时区。 这需要数据库 中的 时区定义。


isnull

采用 TrueFalse,分别对应于 IS NULLIS NOT NULL 的 SQL 查询。

例子:

Entry.objects.filter(pub_date__isnull=True)

SQL 等价于:

SELECT ... WHERE pub_date IS NULL;

regex

区分大小写的正则表达式匹配。

正则表达式语法是正在使用的数据库后端的语法。 对于没有内置正则表达式支持的 SQLite,此功能由(Python)用户定义的 REGEXP 函数提供,因此正则表达式语法是 Python 的 re 模块的语法。

例子:

Entry.objects.get(title__regex=r'^(An?|The) +')

SQL 等效项:

SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL

SELECT ... WHERE REGEXP_LIKE(title, '^(An?|The) +', 'c'); -- Oracle

SELECT ... WHERE title ~ '^(An?|The) +'; -- PostgreSQL

SELECT ... WHERE title REGEXP '^(An?|The) +'; -- SQLite

建议使用原始字符串(例如,r'foo' 而不是 'foo')来传递正则表达式语法。


iregex

不区分大小写的正则表达式匹配。

例子:

Entry.objects.get(title__iregex=r'^(an?|the) +')

SQL 等效项:

SELECT ... WHERE title REGEXP '^(an?|the) +'; -- MySQL

SELECT ... WHERE REGEXP_LIKE(title, '^(an?|the) +', 'i'); -- Oracle

SELECT ... WHERE title ~* '^(an?|the) +'; -- PostgreSQL

SELECT ... WHERE title REGEXP '(?i)^(an?|the) +'; -- SQLite

聚合函数

Django 在 django.db.models 模块中提供了以下聚合函数。 有关如何使用这些聚合函数的详细信息,请参阅 聚合主题指南 。 请参阅 Aggregate 文档以了解如何创建聚合。

警告

SQLite 无法处理开箱即用的日期/时间字段的聚合。 这是因为 SQLite 中没有原生日期/时间字段,而 Django 目前使用文本字段模拟这些功能。 尝试在 SQLite 中的日期/时间字段上使用聚合将引发 NotImplementedError


注解

与空 QuerySet 一起使用时,聚合函数返回 None。 例如,如果 QuerySet 不包含任何条目,则 Sum 聚合函数返回 None 而不是 0。 一个例外是 Count,如果 QuerySet 为空,它会返回 0


所有聚合体都有以下共同的参数:

expressions

引用模型字段的字符串,或 查询表达式


output_field

一个可选参数,表示返回值的 模型字段

注解

在组合多个字段类型时,如果所有字段类型相同,Django 只能确定 output_field。 否则,您必须自己提供 output_field


filter

一个可选的 Q 对象 ,用于过滤聚合的行。

有关示例用法,请参阅 条件聚合注释过滤


**extra

关键字参数,可以为聚合生成的 SQL 提供额外的上下文。


Avg

class Avg(expression, output_field=None, filter=None, **extra)
返回给定表达式的平均值,除非您指定不同的 output_field,否则该平均值必须是数字。
  • 默认别名:<field>__avg
  • 返回类型:float 如果输入是 int,否则与输入字段相同,或者 output_field 如果提供


Count

class Count(expression, distinct=False, filter=None, **extra)

返回通过提供的表达式关联的对象数量。

  • 默认别名:<field>__count

  • 返回类型:int

包含一个可选参数:

distinct

如果为 distinct=True,则计数将仅包括唯一实例。 这是 COUNT(DISTINCT <field>) 的 SQL 等价物。 默认值为 False


Max

class Max(expression, output_field=None, filter=None, **extra)
返回给定表达式的最大值。
  • 默认别名:<field>__max
  • 返回类型:与输入字段相同,或 output_field(如果提供)


Min

class Min(expression, output_field=None, filter=None, **extra)
返回给定表达式的最小值。
  • 默认别名:<field>__min
  • 返回类型:与输入字段相同,或 output_field(如果提供)


StdDev

class StdDev(expression, output_field=None, sample=False, filter=None, **extra)

返回给定表达式中数据的标准差。

  • 默认别名:<field>__stddev

  • 返回类型:float 如果输入是 int,否则与输入字段相同,或者 output_field 如果提供

包含一个可选参数:

sample

默认情况下,StdDev 返回总体标准差。 但是,如果sample=True,则返回值将是样本标准差。

在 2.2 版更改:添加了 SQLite 支持。


Sum

class Sum(expression, output_field=None, filter=None, **extra)
计算给定表达式的所有值的总和。
  • 默认别名:<field>__sum
  • 返回类型:与输入字段相同,或 output_field(如果提供)


Variance

class Variance(expression, output_field=None, sample=False, filter=None, **extra)

返回给定表达式中数据的方差。

  • 默认别名:<field>__variance

  • 返回类型:float 如果输入是 int,否则与输入字段相同,或者 output_field 如果提供

包含一个可选参数:

sample

默认情况下,Variance 返回总体方差。 但是,如果sample=True,返回值将是样本方差。

在 2.2 版更改:添加了 SQLite 支持。