“Django/docs/2.2.x/ref/contrib/postgres/fields”的版本间差异

来自菜鸟教程
Django/docs/2.2.x/ref/contrib/postgres/fields
跳转至:导航、​搜索
(autoload)
 
(Page commit)
 
第1行: 第1行:
 +
{{DISPLAYTITLE:PostgreSQL 特定模型字段 — Django 文档}}
 
<div id="postgresql-specific-model-fields" class="section">
 
<div id="postgresql-specific-model-fields" class="section">
  
= PostgreSQL specific model fields =
+
= PostgreSQL 特有模型字段 =
  
All of these fields are available from the <code>django.contrib.postgres.fields</code>
+
所有这些字段都可以从 <code>django.contrib.postgres.fields</code> 模块获得。
module.
 
  
 
<div id="indexing-these-fields" class="section">
 
<div id="indexing-these-fields" class="section">
  
== Indexing these fields ==
+
== 对这些字段进行索引 ==
  
[[../../../models/indexes#django.db.models|<code>Index</code>]] and [[../../../models/fields#django.db.models.Field|<code>Field.db_index</code>]] both create a
+
[[../../../models/indexes#django.db.models|Index]] [[../../../models/fields#django.db.models.Field|Field.db_index]] 都创建了 B 树索引,这在查询复杂数据类型时不是特别有用。 [[../indexes#django.contrib.postgres.indexes|GinIndex]] [[../indexes#django.contrib.postgres.indexes|GistIndex]] 等索引更适合,尽管索引选择取决于您使用的查询。 通常,对于 [[#range-fields|范围字段]] [[#django.contrib.postgres.fields.HStoreField|HStoreField]],GiST 可能是一个不错的选择,而 GIN 可能对 [[#django.contrib.postgres.fields.ArrayField|ArrayField]] [[#django.contrib.postgres.fields.JSONField|JSONField]] 有帮助。
B-tree index, which isn't particularly helpful when querying complex data types.
 
Indexes such as [[../indexes#django.contrib.postgres.indexes|<code>GinIndex</code>]] and
 
[[../indexes#django.contrib.postgres.indexes|<code>GistIndex</code>]] are better suited, though
 
the index choice is dependent on the queries that you're using. Generally, GiST
 
may be a good choice for the [[#range-fields|<span class="std std-ref">range fields</span>]] and
 
[[#django.contrib.postgres.fields.HStoreField|<code>HStoreField</code>]], and GIN may be helpful for [[#django.contrib.postgres.fields.ArrayField|<code>ArrayField</code>]] and
 
[[#django.contrib.postgres.fields.JSONField|<code>JSONField</code>]].
 
  
  
第23行: 第16行:
 
<div id="arrayfield" class="section">
 
<div id="arrayfield" class="section">
  
== <code>ArrayField</code> ==
+
== ArrayField ==
  
 
<dl>
 
<dl>
<dt>''class'' <code>ArrayField</code><span class="sig-paren">(</span>''<span class="n">base_field</span>'', ''<span class="n">size</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></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">ArrayField</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">base_field</span></span>'', ''<span class="n"><span class="pre">size</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></dt>
<dd><p>A field for storing lists of data. Most field types can be used, you simply
+
<dd><p>用于存储数据列表的字段。 大多数字段类型都可以使用,您只需将另一个字段实例作为 [[#django.contrib.postgres.fields.ArrayField.base_field|base_field]] 传递。 您还可以指定 [[#django.contrib.postgres.fields.ArrayField.size|大小]] <code>ArrayField</code> 可以嵌套存储多维数组。</p>
pass another field instance as the [[#django.contrib.postgres.fields.ArrayField.base_field|<code>base_field</code>]]. You may also specify a [[#django.contrib.postgres.fields.ArrayField.size|<code>size</code>]]. <code>ArrayField</code> can be nested to store multi-dimensional
+
<p>如果您为该字段指定 [[../../../models/fields#django.db.models.Field|default]],请确保它是一个可调用对象,例如 <code>list</code>(对于一个空的默认值)或一个返回列表的可调用对象(例如一个函数)。 不正确地使用 <code>default=[]</code> 会创建一个可变默认值,该默认值在 <code>ArrayField</code> 的所有实例之间共享。</p>
arrays.</p>
 
<p>If you give the field a [[../../../models/fields#django.db.models.Field|<code>default</code>]], ensure
 
it's a callable such as <code>list</code> (for an empty default) or a callable that
 
returns a list (such as a function). Incorrectly using <code>default=[]</code>
 
creates a mutable default that is shared between all instances of
 
<code>ArrayField</code>.</p>
 
 
<dl>
 
<dl>
<dt><code>base_field</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">base_field</span></span></dt>
<dd><p>This is a required argument.</p>
+
<dd><p>这是一个必要的参数。</p>
<p>Specifies the underlying data type and behavior for the array. It
+
<p>指定数组的基础数据类型和行为。 它应该是 [[../../../models/fields#django.db.models|Field]] 子类的一个实例。 例如,它可以是 [[../../../models/fields#django.db.models|IntegerField]] [[../../../models/fields#django.db.models|CharField]]。 大多数字段类型都是允许的,但处理关系数据的字段类型除外([[../../../models/fields#django.db.models|ForeignKey]][[../../../models/fields#django.db.models|OneToOneField]] [[../../../models/fields#django.db.models|ManyToManyField]])。</p>
should be an instance of a subclass of
+
<p>可以嵌套数组字段 - 您可以将 <code>ArrayField</code> 的实例指定为 <code>base_field</code>。 例如:</p>
[[../../../models/fields#django.db.models|<code>Field</code>]]. For example, it could be an
 
[[../../../models/fields#django.db.models|<code>IntegerField</code>]] or a
 
[[../../../models/fields#django.db.models|<code>CharField</code>]]. Most field types are permitted,
 
with the exception of those handling relational data
 
([[../../../models/fields#django.db.models|<code>ForeignKey</code>]],
 
[[../../../models/fields#django.db.models|<code>OneToOneField</code>]] and
 
[[../../../models/fields#django.db.models|<code>ManyToManyField</code>]]).</p>
 
<p>It is possible to nest array fields - you can specify an instance of
 
<code>ArrayField</code> as the <code>base_field</code>. For example:</p>
 
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.contrib.postgres.fields import ArrayField
+
<syntaxhighlight lang="python">from django.contrib.postgres.fields import ArrayField
 
from django.db import models
 
from django.db import models
  
第63行: 第41行:
 
         ),
 
         ),
 
         size=8,
 
         size=8,
     )</pre>
+
     )</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>Transformation of values between the database and the model, validation
+
<p>数据库和模型之间的值的转换、数据和配置的验证以及序列化都是委托给底层基础字段的。</p></dd></dl>
of data and configuration, and serialization are all delegated to the
 
underlying base field.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>size</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">size</span></span></dt>
<dd><p>This is an optional argument.</p>
+
<dd><p>这是一个可选的参数。</p>
<p>If passed, the array will have a maximum size as specified. This will
+
<p>如果通过,数组将具有指定的最大大小。 这将传递给数据库,尽管 PostgreSQL 目前没有强制执行此限制。</p></dd></dl>
be passed to the database, although PostgreSQL at present does not
 
enforce the restriction.</p></dd></dl>
 
 
</dd></dl>
 
</dd></dl>
  
 
<div class="admonition note">
 
<div class="admonition note">
  
注解
+
笔记
  
When nesting <code>ArrayField</code>, whether you use the size parameter or not,
+
嵌套 <code>ArrayField</code> 时,无论是否使用 size 参数,PostgreSQL 都要求数组为矩形:
PostgreSQL requires that the arrays are rectangular:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第91行: 第64行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.contrib.postgres.fields import ArrayField
+
<syntaxhighlight lang="python">from django.contrib.postgres.fields import ArrayField
 
from django.db import models
 
from django.db import models
  
第107行: 第80行:
 
     [2, 3],
 
     [2, 3],
 
     [2],
 
     [2],
])</pre>
+
])</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
If irregular shapes are required, then the underlying field should be made
+
如果需要不规则的形状,那么底层字段应该可以为空,并且值用 <code>None</code> 填充。
nullable and the values padded with <code>None</code>.
 
  
  
第119行: 第91行:
 
<div id="querying-arrayfield" class="section">
 
<div id="querying-arrayfield" class="section">
  
=== Querying <code>ArrayField</code> ===
+
=== 查询ArrayField ===
  
There are a number of custom lookups and transforms for [[#django.contrib.postgres.fields.ArrayField|<code>ArrayField</code>]].
+
[[#django.contrib.postgres.fields.ArrayField|ArrayField]] 有许多自定义查找和转换。 我们将使用以下示例模型:
We will use the following example model:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第128行: 第99行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.contrib.postgres.fields import ArrayField
+
<syntaxhighlight lang="python">from django.contrib.postgres.fields import ArrayField
 
from django.db import models
 
from django.db import models
  
第136行: 第107行:
  
 
     def __str__(self):
 
     def __str__(self):
         return self.name</pre>
+
         return self.name</syntaxhighlight>
  
 
</div>
 
</div>
第143行: 第114行:
 
<div id="contains" class="section">
 
<div id="contains" class="section">
  
<span id="std-fieldlookup-arrayfield.contains"></span><span id="std:fieldlookup-arrayfield.contains"></span>
+
==== contains ====
==== <code>contains</code> ====
 
  
The [[../../../models/querysets#std-fieldlookup-contains|<code>contains</code>]] lookup is overridden on [[#django.contrib.postgres.fields.ArrayField|<code>ArrayField</code>]]. The
+
[[#id1|:lookup:`contains`]] 查找在 [[#django.contrib.postgres.fields.ArrayField|ArrayField]] 上被覆盖。 返回的对象将是那些传递的值是数据子集的对象。 它使用 SQL 运算符 <code>@&gt;</code>。 例如:
returned objects will be those where the values passed are a subset of the
 
data. It uses the SQL operator <code>@&gt;</code>. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第154行: 第122行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Post.objects.create(name='First post', tags=['thoughts', 'django'])
+
<syntaxhighlight lang="python">>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
&gt;&gt;&gt; Post.objects.create(name='Second post', tags=['thoughts'])
+
>>> Post.objects.create(name='Second post', tags=['thoughts'])
&gt;&gt;&gt; Post.objects.create(name='Third post', tags=['tutorial', 'django'])
+
>>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])
  
&gt;&gt;&gt; Post.objects.filter(tags__contains=['thoughts'])
+
>>> Post.objects.filter(tags__contains=['thoughts'])
&lt;QuerySet [&lt;Post: First post&gt;, &lt;Post: Second post&gt;]&gt;
+
<QuerySet [<Post: First post>, <Post: Second post>]>
  
&gt;&gt;&gt; Post.objects.filter(tags__contains=['django'])
+
>>> Post.objects.filter(tags__contains=['django'])
&lt;QuerySet [&lt;Post: First post&gt;, &lt;Post: Third post&gt;]&gt;
+
<QuerySet [<Post: First post>, <Post: Third post>]>
  
&gt;&gt;&gt; Post.objects.filter(tags__contains=['django', 'thoughts'])
+
>>> Post.objects.filter(tags__contains=['django', 'thoughts'])
&lt;QuerySet [&lt;Post: First post&gt;]&gt;</pre>
+
<QuerySet [<Post: First post>]></syntaxhighlight>
  
 
</div>
 
</div>
第174行: 第142行:
 
<div id="contained-by" class="section">
 
<div id="contained-by" class="section">
  
<span id="std-fieldlookup-arrayfield.contained_by"></span><span id="std:fieldlookup-arrayfield.contained_by"></span>
+
==== contained_by ====
==== <code>contained_by</code> ====
 
  
This is the inverse of the [[#std-fieldlookup-arrayfield.contains|<code>contains</code>]] lookup -
+
这是相反的 [[#id3|:lookup:`包含 `]] 查找 - 返回的对象将是那些数据是传递值的子集的对象。 它使用 SQL 运算符 <code>&lt;@</code>。 例如:
the objects returned will be those where the data is a subset of the values
 
passed. It uses the SQL operator <code>&lt;@</code>. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第185行: 第150行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Post.objects.create(name='First post', tags=['thoughts', 'django'])
+
<syntaxhighlight lang="python">>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
&gt;&gt;&gt; Post.objects.create(name='Second post', tags=['thoughts'])
+
>>> Post.objects.create(name='Second post', tags=['thoughts'])
&gt;&gt;&gt; Post.objects.create(name='Third post', tags=['tutorial', 'django'])
+
>>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])
  
&gt;&gt;&gt; Post.objects.filter(tags__contained_by=['thoughts', 'django'])
+
>>> Post.objects.filter(tags__contained_by=['thoughts', 'django'])
&lt;QuerySet [&lt;Post: First post&gt;, &lt;Post: Second post&gt;]&gt;
+
<QuerySet [<Post: First post>, <Post: Second post>]>
  
&gt;&gt;&gt; Post.objects.filter(tags__contained_by=['thoughts', 'django', 'tutorial'])
+
>>> Post.objects.filter(tags__contained_by=['thoughts', 'django', 'tutorial'])
&lt;QuerySet [&lt;Post: First post&gt;, &lt;Post: Second post&gt;, &lt;Post: Third post&gt;]&gt;</pre>
+
<QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]></syntaxhighlight>
  
 
</div>
 
</div>
第202行: 第167行:
 
<div id="overlap" class="section">
 
<div id="overlap" class="section">
  
<span id="std-fieldlookup-arrayfield.overlap"></span><span id="std:fieldlookup-arrayfield.overlap"></span>
+
==== overlap ====
==== <code>overlap</code> ====
 
  
Returns objects where the data shares any results with the values passed. Uses
+
返回数据与传递的值共享任何结果的对象。 使用 SQL 运算符 <code>&amp;&amp;</code>。 例如:
the SQL operator <code>&amp;&amp;</code>. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第212行: 第175行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Post.objects.create(name='First post', tags=['thoughts', 'django'])
+
<syntaxhighlight lang="python">>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
&gt;&gt;&gt; Post.objects.create(name='Second post', tags=['thoughts'])
+
>>> Post.objects.create(name='Second post', tags=['thoughts'])
&gt;&gt;&gt; Post.objects.create(name='Third post', tags=['tutorial', 'django'])
+
>>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])
  
&gt;&gt;&gt; Post.objects.filter(tags__overlap=['thoughts'])
+
>>> Post.objects.filter(tags__overlap=['thoughts'])
&lt;QuerySet [&lt;Post: First post&gt;, &lt;Post: Second post&gt;]&gt;
+
<QuerySet [<Post: First post>, <Post: Second post>]>
  
&gt;&gt;&gt; Post.objects.filter(tags__overlap=['thoughts', 'tutorial'])
+
>>> Post.objects.filter(tags__overlap=['thoughts', 'tutorial'])
&lt;QuerySet [&lt;Post: First post&gt;, &lt;Post: Second post&gt;, &lt;Post: Third post&gt;]&gt;</pre>
+
<QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]></syntaxhighlight>
  
 
</div>
 
</div>
第229行: 第192行:
 
<div id="len" class="section">
 
<div id="len" class="section">
  
<span id="std-fieldlookup-arrayfield.len"></span><span id="std:fieldlookup-arrayfield.len"></span>
+
==== len ====
==== <code>len</code> ====
 
  
Returns the length of the array. The lookups available afterwards are those
+
返回数组的长度。 之后可用的查找是可用于 [[../../../models/fields#django.db.models|IntegerField]] 的那些。 例如:
available for [[../../../models/fields#django.db.models|<code>IntegerField</code>]]. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第239行: 第200行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Post.objects.create(name='First post', tags=['thoughts', 'django'])
+
<syntaxhighlight lang="python">>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
&gt;&gt;&gt; Post.objects.create(name='Second post', tags=['thoughts'])
+
>>> Post.objects.create(name='Second post', tags=['thoughts'])
  
&gt;&gt;&gt; Post.objects.filter(tags__len=1)
+
>>> Post.objects.filter(tags__len=1)
&lt;QuerySet [&lt;Post: Second post&gt;]&gt;</pre>
+
<QuerySet [<Post: Second post>]></syntaxhighlight>
  
 
</div>
 
</div>
第252行: 第213行:
 
<div id="index-transforms" class="section">
 
<div id="index-transforms" class="section">
  
<span id="std-fieldlookup-arrayfield.index"></span><span id="std:fieldlookup-arrayfield.index"></span>
+
==== 索引转换 ====
==== Index transforms ====
 
  
Index transforms index into the array. Any non-negative integer can be used.
+
索引将索引转换为数组。 可以使用任何非负整数。 如果超过数组的 [[#django.contrib.postgres.fields.ArrayField.size|大小]] ,则没有错误。 转换后可用的查找来自 [[#django.contrib.postgres.fields.ArrayField.base_field|base_field]]。 例如:
There are no errors if it exceeds the [[#django.contrib.postgres.fields.ArrayField.size|<code>size</code>]] of the
 
array. The lookups available after the transform are those from the
 
[[#django.contrib.postgres.fields.ArrayField.base_field|<code>base_field</code>]]. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第264行: 第221行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Post.objects.create(name='First post', tags=['thoughts', 'django'])
+
<syntaxhighlight lang="python">>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
&gt;&gt;&gt; Post.objects.create(name='Second post', tags=['thoughts'])
+
>>> Post.objects.create(name='Second post', tags=['thoughts'])
  
&gt;&gt;&gt; Post.objects.filter(tags__0='thoughts')
+
>>> Post.objects.filter(tags__0='thoughts')
&lt;QuerySet [&lt;Post: First post&gt;, &lt;Post: Second post&gt;]&gt;
+
<QuerySet [<Post: First post>, <Post: Second post>]>
  
&gt;&gt;&gt; Post.objects.filter(tags__1__iexact='Django')
+
>>> Post.objects.filter(tags__1__iexact='Django')
&lt;QuerySet [&lt;Post: First post&gt;]&gt;
+
<QuerySet [<Post: First post>]>
  
&gt;&gt;&gt; Post.objects.filter(tags__276='javascript')
+
>>> Post.objects.filter(tags__276='javascript')
&lt;QuerySet []&gt;</pre>
+
<QuerySet []></syntaxhighlight>
  
 
</div>
 
</div>
第281行: 第238行:
 
<div class="admonition note">
 
<div class="admonition note">
  
注解
+
笔记
  
PostgreSQL uses 1-based indexing for array fields when writing raw SQL.
+
PostgreSQL 在编写原始 SQL 时对数组字段使用基于 1 的索引。 然而,这些索引和那些用于 [[#id5|:lookup:`切片 `]] 使用基于 0 的索引以与 Python 保持一致。
However these indexes and those used in [[#std-fieldlookup-arrayfield.slice|<code>slices</code>]]
 
use 0-based indexing to be consistent with Python.
 
  
  
第293行: 第248行:
 
<div id="slice-transforms" class="section">
 
<div id="slice-transforms" class="section">
  
<span id="std-fieldlookup-arrayfield.slice"></span><span id="std:fieldlookup-arrayfield.slice"></span>
+
==== 切片转换 ====
==== Slice transforms ====
 
  
Slice transforms take a slice of the array. Any two non-negative integers can
+
切片变换采用数组的切片。 可以使用任何两个非负整数,用单个下划线分隔。 转换后可用的查找不会改变。 例如:
be used, separated by a single underscore. The lookups available after the
 
transform do not change. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第304行: 第256行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Post.objects.create(name='First post', tags=['thoughts', 'django'])
+
<syntaxhighlight lang="python">>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
&gt;&gt;&gt; Post.objects.create(name='Second post', tags=['thoughts'])
+
>>> Post.objects.create(name='Second post', tags=['thoughts'])
&gt;&gt;&gt; Post.objects.create(name='Third post', tags=['django', 'python', 'thoughts'])
+
>>> Post.objects.create(name='Third post', tags=['django', 'python', 'thoughts'])
  
&gt;&gt;&gt; Post.objects.filter(tags__0_1=['thoughts'])
+
>>> Post.objects.filter(tags__0_1=['thoughts'])
&lt;QuerySet [&lt;Post: First post&gt;, &lt;Post: Second post&gt;]&gt;
+
<QuerySet [<Post: First post>, <Post: Second post>]>
  
&gt;&gt;&gt; Post.objects.filter(tags__0_2__contains=['thoughts'])
+
>>> Post.objects.filter(tags__0_2__contains=['thoughts'])
&lt;QuerySet [&lt;Post: First post&gt;, &lt;Post: Second post&gt;]&gt;</pre>
+
<QuerySet [<Post: First post>, <Post: Second post>]></syntaxhighlight>
  
 
</div>
 
</div>
第319行: 第271行:
 
<div class="admonition note">
 
<div class="admonition note">
  
注解
+
笔记
  
PostgreSQL uses 1-based indexing for array fields when writing raw SQL.
+
PostgreSQL 在编写原始 SQL 时对数组字段使用基于 1 的索引。 然而,这些切片和那些用于 [[#id7|:lookup:`索引 `]] 使用基于 0 的索引以与 Python 保持一致。
However these slices and those used in [[#std-fieldlookup-arrayfield.index|<code>indexes</code>]]
 
use 0-based indexing to be consistent with Python.
 
  
  
第329行: 第279行:
 
<div class="admonition-multidimensional-arrays-with-indexes-and-slices admonition">
 
<div class="admonition-multidimensional-arrays-with-indexes-and-slices admonition">
  
Multidimensional arrays with indexes and slices
+
带索引和切片的多维数组
  
PostgreSQL has some rather esoteric behavior when using indexes and slices
+
在多维数组上使用索引和切片时,PostgreSQL 有一些相当深奥的行为。 使用索引来深入到最终的底层数据总是有效的,但大多数其他切片在数据库级别的行为很奇怪,并且无法以逻辑一致的方式被 Django 支持。
on multidimensional arrays. It will always work to use indexes to reach
 
down to the final underlying data, but most other slices behave strangely
 
at the database level and cannot be supported in a logical, consistent
 
fashion by Django.
 
  
  
第347行: 第293行:
 
<div id="citext-fields" class="section">
 
<div id="citext-fields" class="section">
  
== <code>CIText</code> fields ==
+
== CIText 字段 ==
  
 
<dl>
 
<dl>
<dt>''class'' <code>CIText</code><span class="sig-paren">(</span>''<span class="o">**</span><span class="n">options</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">CIText</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">options</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>A mixin to create case-insensitive text fields backed by the [https://www.postgresql.org/docs/current/citext.html citext] type.
+
<dd><p>创建由 [https://www.postgresql.org/docs/current/citext.html citext] 类型支持的不区分大小写的文本字段的 mixin。 在使用之前阅读 [https://www.postgresql.org/docs/current/citext.html#id-1.11.7.17.7 性能注意事项] </p>
Read about [https://www.postgresql.org/docs/current/citext.html#id-1.11.7.17.7 the performance considerations] prior to using it.</p>
+
<p>要使用<code>citext</code>,在第一次<code>CreateModel</code>迁移操作之前,使用[[../operations#django.contrib.postgres.operations|CITextExtension]]操作在PostgreSQL中[[../operations#create-postgresql-extensions|设置citext扩展]]。</p>
<p>To use <code>citext</code>, use the [[../operations#django.contrib.postgres.operations|<code>CITextExtension</code>]] operation to
+
<p>如果您使用 <code>CIText</code> 字段的 [[#django.contrib.postgres.fields.ArrayField|ArrayField]],则必须在 [[#id9|:setting:`INSTALLED_APPS`]] 中添加 <code>'django.contrib.postgres'</code>,否则字段值将显示为类似 <code>'{thoughts,django}'</code> 的字符串。</p>
[[../operations#create-postgresql-extensions|<span class="std std-ref">setup the citext extension</span>]] in
+
<p>提供了几个使用混入的字段:</p></dd></dl>
PostgreSQL before the first <code>CreateModel</code> migration operation.</p>
 
<p>If you're using an [[#django.contrib.postgres.fields.ArrayField|<code>ArrayField</code>]]
 
of <code>CIText</code> fields, you must add <code>'django.contrib.postgres'</code> in your
 
[[../../../settings#std-setting-INSTALLED_APPS|<code>INSTALLED_APPS</code>]], otherwise field values will appear as strings
 
like <code>'{thoughts,django}'</code>.</p>
 
<p>Several fields that use the mixin are provided:</p></dd></dl>
 
  
; ''class'' <code>CICharField</code><span class="sig-paren">(</span>''<span class="o">**</span><span class="n">options</span>''<span class="sig-paren">)</span>
+
; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">CICharField</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">options</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
; ''class'' <code>CIEmailField</code><span class="sig-paren">(</span>''<span class="o">**</span><span class="n">options</span>''<span class="sig-paren">)</span>
+
; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">CIEmailField</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">options</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
 
<dl>
 
<dl>
<dt>''class'' <code>CITextField</code><span class="sig-paren">(</span>''<span class="o">**</span><span class="n">options</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">CITextField</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">options</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>These fields subclass [[../../../models/fields#django.db.models|<code>CharField</code>]],
+
<dd><p>这些字段分别是 [[../../../models/fields#django.db.models|CharField]][[../../../models/fields#django.db.models|EmailField]] [[../../../models/fields#django.db.models|TextField]] 的子类。</p>
[[../../../models/fields#django.db.models|<code>EmailField</code>]], and
+
<p><code>max_length</code> 不会在数据库中强制执行,因为 <code>citext</code> 的行为类似于 PostgreSQL <code>text</code> 类型。</p></dd></dl>
[[../../../models/fields#django.db.models|<code>TextField</code>]], respectively.</p>
 
<p><code>max_length</code> won't be enforced in the database since <code>citext</code> behaves
 
similar to PostgreSQL's <code>text</code> type.</p></dd></dl>
 
  
  
第380行: 第317行:
 
<div id="hstorefield" class="section">
 
<div id="hstorefield" class="section">
  
== <code>HStoreField</code> ==
+
== HStoreField ==
  
 
<dl>
 
<dl>
<dt>''class'' <code>HStoreField</code><span class="sig-paren">(</span>''<span class="o">**</span><span class="n">options</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">HStoreField</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">options</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>A field for storing key-value pairs. The Python data type used is a
+
<dd><p>用于存储键值对的字段。 使用的 Python 数据类型是 <code>dict</code>。 键必须是字符串,值可以是字符串或空值(Python 中的 <code>None</code>)。</p>
<code>dict</code>. Keys must be strings, and values may be either strings or nulls
+
<p>要使用此字段,您需要:</p>
(<code>None</code> in Python).</p>
 
<p>To use this field, you'll need to:</p>
 
 
<ol>
 
<ol>
<li><p>Add <code>'django.contrib.postgres'</code> in your [[../../../settings#std-setting-INSTALLED_APPS|<code>INSTALLED_APPS</code>]].</p></li>
+
<li><p>在您的 [[#id11|:setting:`INSTALLED_APPS`]] 中添加 <code>'django.contrib.postgres'</code></p></li>
<li><p>[[../operations#create-postgresql-extensions|<span class="std std-ref">Setup the hstore extension</span>]] in
+
<li><p>[[../operations#create-postgresql-extensions|在PostgreSQL中设置hstore扩展]]</p></li></ol>
PostgreSQL.</p></li></ol>
 
  
<p>You'll see an error like <code>can't adapt type 'dict'</code> if you skip the first
+
<p>如果您跳过第一步,您将看到类似 <code>can't adapt type 'dict'</code> 的错误,如果您跳过第二步,则会看到 <code>type &quot;hstore&quot; does not exist</code> 之类的错误。</p></dd></dl>
step, or <code>type &quot;hstore&quot; does not exist</code> if you skip the second.</p></dd></dl>
 
  
 
<div class="admonition note">
 
<div class="admonition note">
  
注解
+
笔记
  
On occasions it may be useful to require or restrict the keys which are
+
有时,要求或限制对给定字段有效的键可能很有用。 这可以使用 [[../validators#django.contrib.postgres.validators|KeysValidator]] 来完成。
valid for a given field. This can be done using the
 
[[../validators#django.contrib.postgres.validators|<code>KeysValidator</code>]].
 
  
  
第408行: 第339行:
 
<div id="querying-hstorefield" class="section">
 
<div id="querying-hstorefield" class="section">
  
=== Querying <code>HStoreField</code> ===
+
=== 查询HStoreField ===
  
In addition to the ability to query by key, there are a number of custom
+
除了按键查询的能力外,还有许多可用于 <code>HStoreField</code> 的自定义查找。
lookups available for <code>HStoreField</code>.
 
  
We will use the following example model:
+
我们将使用以下示例模型:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第419行: 第349行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.contrib.postgres.fields import HStoreField
+
<syntaxhighlight lang="python">from django.contrib.postgres.fields import HStoreField
 
from django.db import models
 
from django.db import models
  
第427行: 第357行:
  
 
     def __str__(self):
 
     def __str__(self):
         return self.name</pre>
+
         return self.name</syntaxhighlight>
  
 
</div>
 
</div>
第434行: 第364行:
 
<div id="key-lookups" class="section">
 
<div id="key-lookups" class="section">
  
<span id="std-fieldlookup-hstorefield.key"></span><span id="std:fieldlookup-hstorefield.key"></span>
+
==== 键查找 ====
==== Key lookups ====
 
  
To query based on a given key, you simply use that key as the lookup name:
+
要基于给定的键进行查询,您只需使用该键作为查找名称:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第443行: 第372行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
+
<syntaxhighlight lang="python">>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
&gt;&gt;&gt; Dog.objects.create(name='Meg', data={'breed': 'collie'})
+
>>> Dog.objects.create(name='Meg', data={'breed': 'collie'})
  
&gt;&gt;&gt; Dog.objects.filter(data__breed='collie')
+
>>> Dog.objects.filter(data__breed='collie')
&lt;QuerySet [&lt;Dog: Meg&gt;]&gt;</pre>
+
<QuerySet [<Dog: Meg>]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
You can chain other lookups after key lookups:
+
您可以在键查找后链接其他查找:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第458行: 第387行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Dog.objects.filter(data__breed__contains='l')
+
<syntaxhighlight lang="python">>>> Dog.objects.filter(data__breed__contains='l')
&lt;QuerySet [&lt;Dog: Rufus&gt;, &lt;Dog: Meg&gt;]&gt;</pre>
+
<QuerySet [<Dog: Rufus>, <Dog: Meg>]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
If the key you wish to query by clashes with the name of another lookup, you
+
如果您希望查询的键与另一个查找的名称发生冲突,您需要改用 [[#id13|:lookup:`hstorefield.contains`]] 查找。
need to use the [[#std-fieldlookup-hstorefield.contains|<code>hstorefield.contains</code>]] lookup instead.
 
  
 
<div class="admonition warning">
 
<div class="admonition warning">
第471行: 第399行:
 
警告
 
警告
  
Since any string could be a key in a hstore value, any lookup other than
+
由于任何字符串都可以是 hstore 值中的键,因此除下面列出的那些之外的任何查找都将被解释为键查找。 没有错误被提出。 输入错误时要格外小心,并始终检查您的查询是否按预期工作。
those listed below will be interpreted as a key lookup. No errors are
 
raised. Be extra careful for typing mistakes, and always check your queries
 
work as you intend.
 
  
  
第480行: 第405行:
  
 
</div>
 
</div>
<div id="std-fieldlookup-hstorefield.contains" class="section">
+
<div id="id15" class="section">
  
<span id="std:fieldlookup-hstorefield.contains"></span><span id="id1"></span>
+
==== contains ====
==== <code>contains</code> ====
 
  
The [[../../../models/querysets#std-fieldlookup-contains|<code>contains</code>]] lookup is overridden on
+
[[#id16|:lookup:`contains`]] 查找在 [[#django.contrib.postgres.fields.HStoreField|HStoreField]] 上被覆盖。 返回的对象是那些给定的 <code>dict</code> 键值对都包含在字段中的对象。 它使用 SQL 运算符 <code>@&gt;</code>。 例如:
[[#django.contrib.postgres.fields.HStoreField|<code>HStoreField</code>]]. The returned objects are
 
those where the given <code>dict</code> of key-value pairs are all contained in the
 
field. It uses the SQL operator <code>@&gt;</code>. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第494行: 第415行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'})
+
<syntaxhighlight lang="python">>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'})
&gt;&gt;&gt; Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
+
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
&gt;&gt;&gt; Dog.objects.create(name='Fred', data={})
+
>>> Dog.objects.create(name='Fred', data={})
  
&gt;&gt;&gt; Dog.objects.filter(data__contains={'owner': 'Bob'})
+
>>> Dog.objects.filter(data__contains={'owner': 'Bob'})
&lt;QuerySet [&lt;Dog: Rufus&gt;, &lt;Dog: Meg&gt;]&gt;
+
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>
  
&gt;&gt;&gt; Dog.objects.filter(data__contains={'breed': 'collie'})
+
>>> Dog.objects.filter(data__contains={'breed': 'collie'})
&lt;QuerySet [&lt;Dog: Meg&gt;]&gt;</pre>
+
<QuerySet [<Dog: Meg>]></syntaxhighlight>
  
 
</div>
 
</div>
第509行: 第430行:
  
 
</div>
 
</div>
<div id="std-fieldlookup-hstorefield.contained_by" class="section">
+
<div id="id18" class="section">
  
<span id="std:fieldlookup-hstorefield.contained_by"></span><span id="id2"></span>
+
==== contained_by ====
==== <code>contained_by</code> ====
 
  
This is the inverse of the [[#std-fieldlookup-hstorefield.contains|<code>contains</code>]] lookup -
+
这是相反的 [[#id19|:lookup:`包含 `]] 查找 - 返回的对象将是那些对象上的键值对是传递值中键值对的子集的对象。 它使用 SQL 运算符 <code>&lt;@</code>。 例如:
the objects returned will be those where the key-value pairs on the object are
 
a subset of those in the value passed. It uses the SQL operator <code>&lt;@</code>. For
 
example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第523行: 第440行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'})
+
<syntaxhighlight lang="python">>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'})
&gt;&gt;&gt; Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
+
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
&gt;&gt;&gt; Dog.objects.create(name='Fred', data={})
+
>>> Dog.objects.create(name='Fred', data={})
  
&gt;&gt;&gt; Dog.objects.filter(data__contained_by={'breed': 'collie', 'owner': 'Bob'})
+
>>> Dog.objects.filter(data__contained_by={'breed': 'collie', 'owner': 'Bob'})
&lt;QuerySet [&lt;Dog: Meg&gt;, &lt;Dog: Fred&gt;]&gt;
+
<QuerySet [<Dog: Meg>, <Dog: Fred>]>
  
&gt;&gt;&gt; Dog.objects.filter(data__contained_by={'breed': 'collie'})
+
>>> Dog.objects.filter(data__contained_by={'breed': 'collie'})
&lt;QuerySet [&lt;Dog: Fred&gt;]&gt;</pre>
+
<QuerySet [<Dog: Fred>]></syntaxhighlight>
  
 
</div>
 
</div>
第540行: 第457行:
 
<div id="has-key" class="section">
 
<div id="has-key" class="section">
  
<span id="std-fieldlookup-hstorefield.has_key"></span><span id="std:fieldlookup-hstorefield.has_key"></span>
+
==== has_key ====
==== <code>has_key</code> ====
 
  
Returns objects where the given key is in the data. Uses the SQL operator
+
返回给定键在数据中的对象。 使用 SQL 运算符 <code>?</code>。 例如:
<code>?</code>. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第550行: 第465行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
+
<syntaxhighlight lang="python">>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
&gt;&gt;&gt; Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
+
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
  
&gt;&gt;&gt; Dog.objects.filter(data__has_key='owner')
+
>>> Dog.objects.filter(data__has_key='owner')
&lt;QuerySet [&lt;Dog: Meg&gt;]&gt;</pre>
+
<QuerySet [<Dog: Meg>]></syntaxhighlight>
  
 
</div>
 
</div>
第563行: 第478行:
 
<div id="has-any-keys" class="section">
 
<div id="has-any-keys" class="section">
  
<span id="std-fieldlookup-hstorefield.has_any_keys"></span><span id="std:fieldlookup-hstorefield.has_any_keys"></span>
+
==== has_any_keys ====
==== <code>has_any_keys</code> ====
 
  
Returns objects where any of the given keys are in the data. Uses the SQL
+
返回任何给定键在数据中的对象。 使用 SQL 运算符 <code>?|</code>。 例如:
operator <code>?|</code>. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第573行: 第486行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
+
<syntaxhighlight lang="python">>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
&gt;&gt;&gt; Dog.objects.create(name='Meg', data={'owner': 'Bob'})
+
>>> Dog.objects.create(name='Meg', data={'owner': 'Bob'})
&gt;&gt;&gt; Dog.objects.create(name='Fred', data={})
+
>>> Dog.objects.create(name='Fred', data={})
  
&gt;&gt;&gt; Dog.objects.filter(data__has_any_keys=['owner', 'breed'])
+
>>> Dog.objects.filter(data__has_any_keys=['owner', 'breed'])
&lt;QuerySet [&lt;Dog: Rufus&gt;, &lt;Dog: Meg&gt;]&gt;</pre>
+
<QuerySet [<Dog: Rufus>, <Dog: Meg>]></syntaxhighlight>
  
 
</div>
 
</div>
第587行: 第500行:
 
<div id="has-keys" class="section">
 
<div id="has-keys" class="section">
  
<span id="std-fieldlookup-hstorefield.has_keys"></span><span id="std:fieldlookup-hstorefield.has_keys"></span>
+
==== has_keys ====
==== <code>has_keys</code> ====
 
  
Returns objects where all of the given keys are in the data. Uses the SQL operator
+
返回所有给定键都在数据中的对象。 使用 SQL 运算符 <code>?&amp;</code>。 例如:
<code>?&amp;</code>. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第597行: 第508行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Dog.objects.create(name='Rufus', data={})
+
<syntaxhighlight lang="python">>>> Dog.objects.create(name='Rufus', data={})
&gt;&gt;&gt; Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
+
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
  
&gt;&gt;&gt; Dog.objects.filter(data__has_keys=['breed', 'owner'])
+
>>> Dog.objects.filter(data__has_keys=['breed', 'owner'])
&lt;QuerySet [&lt;Dog: Meg&gt;]&gt;</pre>
+
<QuerySet [<Dog: Meg>]></syntaxhighlight>
  
 
</div>
 
</div>
第610行: 第521行:
 
<div id="keys" class="section">
 
<div id="keys" class="section">
  
<span id="std-fieldlookup-hstorefield.keys"></span><span id="std:fieldlookup-hstorefield.keys"></span>
+
==== keys ====
==== <code>keys</code> ====
 
  
Returns objects where the array of keys is the given value. Note that the order
+
返回键数组为给定值的对象。 请注意,不能保证顺序是可靠的,因此此转换主要用于与 [[#django.contrib.postgres.fields.ArrayField|ArrayField]] 上的查找结合使用。 使用 SQL 函数 <code>akeys()</code>。 例如:
is not guaranteed to be reliable, so this transform is mainly useful for using
 
in conjunction with lookups on
 
[[#django.contrib.postgres.fields.ArrayField|<code>ArrayField</code>]]. Uses the SQL function
 
<code>akeys()</code>. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第623行: 第529行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Dog.objects.create(name='Rufus', data={'toy': 'bone'})
+
<syntaxhighlight lang="python">>>> Dog.objects.create(name='Rufus', data={'toy': 'bone'})
&gt;&gt;&gt; Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
+
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
  
&gt;&gt;&gt; Dog.objects.filter(data__keys__overlap=['breed', 'toy'])
+
>>> Dog.objects.filter(data__keys__overlap=['breed', 'toy'])
&lt;QuerySet [&lt;Dog: Rufus&gt;, &lt;Dog: Meg&gt;]&gt;</pre>
+
<QuerySet [<Dog: Rufus>, <Dog: Meg>]></syntaxhighlight>
  
 
</div>
 
</div>
第636行: 第542行:
 
<div id="values" class="section">
 
<div id="values" class="section">
  
<span id="std-fieldlookup-hstorefield.values"></span><span id="std:fieldlookup-hstorefield.values"></span>
+
==== values ====
==== <code>values</code> ====
 
  
Returns objects where the array of values is the given value. Note that the
+
返回值数组是给定值的对象。 请注意,不能保证顺序是可靠的,因此此转换主要用于与 [[#django.contrib.postgres.fields.ArrayField|ArrayField]] 上的查找结合使用。 使用 SQL 函数 <code>avalues()</code>。 例如:
order is not guaranteed to be reliable, so this transform is mainly useful for
 
using in conjunction with lookups on
 
[[#django.contrib.postgres.fields.ArrayField|<code>ArrayField</code>]]. Uses the SQL function
 
<code>avalues()</code>. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第649行: 第550行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
+
<syntaxhighlight lang="python">>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
&gt;&gt;&gt; Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
+
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
  
&gt;&gt;&gt; Dog.objects.filter(data__values__contains=['collie'])
+
>>> Dog.objects.filter(data__values__contains=['collie'])
&lt;QuerySet [&lt;Dog: Meg&gt;]&gt;</pre>
+
<QuerySet [<Dog: Meg>]></syntaxhighlight>
  
 
</div>
 
</div>
第666行: 第567行:
 
<div id="jsonfield" class="section">
 
<div id="jsonfield" class="section">
  
== <code>JSONField</code> ==
+
== JSONField ==
  
 
<dl>
 
<dl>
<dt>''class'' <code>JSONField</code><span class="sig-paren">(</span>''<span class="n">encoder</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></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">JSONField</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">encoder</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></dt>
<dd><p>A field for storing JSON encoded data. In Python the data is represented in
+
<dd><p>用于存储 JSON 编码数据的字段。 在 Python 中,数据以其 Python 原生格式表示:字典、列表、字符串、数字、布尔值和 <code>None</code></p>
its Python native format: dictionaries, lists, strings, numbers, booleans
 
and <code>None</code>.</p>
 
 
<dl>
 
<dl>
<dt><code>encoder</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">encoder</span></span></dt>
<dd><p>An optional JSON-encoding class to serialize data types not supported
+
<dd><p>一个可选的 JSON 编码类,用于序列化标准 JSON 序列化程序(<code>datetime</code><code>uuid</code> 等)不支持的数据类型。 例如,您可以使用 [[../../../../topics/serialization#django.core.serializers.json|DjangoJSONEncoder]] 类或任何其他 <code>json.JSONEncoder</code> 子类。</p>
by the standard JSON serializer (<code>datetime</code>, <code>uuid</code>, etc.). For
+
<p>从数据库中检索值时,它将采用自定义编码器选择的格式(通常是字符串),因此您需要采取额外的步骤将值转换回初始数据类型 ( [[../../../models/instances#django.db.models.Model|Model.from_db()]] [[../../../models/fields#django.db.models.Field|Field.from_db_value()]] 是用于此目的的两个可能的钩子)。 您的反序列化可能需要考虑到您无法确定输入类型的事实。 例如,您冒着返回 <code>datetime</code> 的风险,该字符串实际上是一个恰好与为 <code>datetime</code> 选择的格式相同的字符串。</p></dd></dl>
example, you can use the
 
[[../../../../topics/serialization#django.core.serializers.json|<code>DjangoJSONEncoder</code>]] class or any
 
other <code>json.JSONEncoder</code> subclass.</p>
 
<p>When the value is retrieved from the database, it will be in the format
 
chosen by the custom encoder (most often a string), so you'll need to
 
take extra steps to convert the value back to the initial data type
 
([[../../../models/instances#django.db.models.Model|<code>Model.from_db()</code>]] and
 
[[../../../models/fields#django.db.models.Field|<code>Field.from_db_value()</code>]]
 
are two possible hooks for that purpose). Your deserialization may need
 
to account for the fact that you can't be certain of the input type.
 
For example, you run the risk of returning a <code>datetime</code> that was
 
actually a string that just happened to be in the same format chosen
 
for <code>datetime</code>s.</p></dd></dl>
 
  
<p>If you give the field a [[../../../models/fields#django.db.models.Field|<code>default</code>]], ensure
+
<p>如果你给这个字段一个 [[../../../models/fields#django.db.models.Field|default]],确保它是一个可调用的,比如 <code>dict</code>(对于一个空的默认值)或一个返回一个字典的可调用的(比如一个函数)。 不正确地使用 <code>default={}</code> 会创建一个可变默认值,该默认值在 <code>JSONField</code> 的所有实例之间共享。</p></dd></dl>
it's a callable such as <code>dict</code> (for an empty default) or a callable that
 
returns a dict (such as a function). Incorrectly using <code>default={}</code>
 
creates a mutable default that is shared between all instances of
 
<code>JSONField</code>.</p></dd></dl>
 
  
 
<div class="admonition note">
 
<div class="admonition note">
  
注解
+
笔记
  
PostgreSQL has two native JSON based data types: <code>json</code> and <code>jsonb</code>.
+
PostgreSQL 有两种基于 JSON 的原生数据类型:<code>json</code> <code>jsonb</code>。 它们之间的主要区别在于它们的存储方式和查询方式。 PostgreSQL <code>json</code> 字段存储为 JSON 的原始字符串表示形式,并且必须在基于键查询时即时解码。 <code>jsonb</code> 字段基于允许索引的 JSON 的实际结构进行存储。 权衡是写入 <code>jsonb</code> 字段的少量额外成本。 <code>JSONField</code> 使用 <code>jsonb</code>
The main difference between them is how they are stored and how they can be
 
queried. PostgreSQL's <code>json</code> field is stored as the original string
 
representation of the JSON and must be decoded on the fly when queried
 
based on keys. The <code>jsonb</code> field is stored based on the actual structure
 
of the JSON which allows indexing. The trade-off is a small additional cost
 
on writing to the <code>jsonb</code> field. <code>JSONField</code> uses <code>jsonb</code>.
 
  
  
第713行: 第589行:
 
<div id="querying-jsonfield" class="section">
 
<div id="querying-jsonfield" class="section">
  
=== Querying <code>JSONField</code> ===
+
=== 查询JSONField ===
  
We will use the following example model:
+
我们将使用以下示例模型:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第721行: 第597行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.contrib.postgres.fields import JSONField
+
<syntaxhighlight lang="python">from django.contrib.postgres.fields import JSONField
 
from django.db import models
 
from django.db import models
  
第729行: 第605行:
  
 
     def __str__(self):
 
     def __str__(self):
         return self.name</pre>
+
         return self.name</syntaxhighlight>
  
 
</div>
 
</div>
第736行: 第612行:
 
<div id="key-index-and-path-lookups" class="section">
 
<div id="key-index-and-path-lookups" class="section">
  
<span id="std-fieldlookup-jsonfield.key"></span><span id="std:fieldlookup-jsonfield.key"></span>
+
==== 键、索引和路径查找 ====
==== Key, index, and path lookups ====
 
  
To query based on a given dictionary key, simply use that key as the lookup
+
要基于给定的字典键进行查询,只需使用该键作为查找名称:
name:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第746行: 第620行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Dog.objects.create(name='Rufus', data={
+
<syntaxhighlight lang="python">>>> Dog.objects.create(name='Rufus', data={
 
...    'breed': 'labrador',
 
...    'breed': 'labrador',
 
...    'owner': {
 
...    'owner': {
第755行: 第629行:
 
...    },
 
...    },
 
... })
 
... })
&gt;&gt;&gt; Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': None})
+
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': None})
  
&gt;&gt;&gt; Dog.objects.filter(data__breed='collie')
+
>>> Dog.objects.filter(data__breed='collie')
&lt;QuerySet [&lt;Dog: Meg&gt;]&gt;</pre>
+
<QuerySet [<Dog: Meg>]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Multiple keys can be chained together to form a path lookup:
+
多个键可以链接在一起以形成路径查找:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第769行: 第643行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Dog.objects.filter(data__owner__name='Bob')
+
<syntaxhighlight lang="python">>>> Dog.objects.filter(data__owner__name='Bob')
&lt;QuerySet [&lt;Dog: Rufus&gt;]&gt;</pre>
+
<QuerySet [<Dog: Rufus>]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
If the key is an integer, it will be interpreted as an index lookup in an
+
如果键是整数,它将被解释为数组中的索引查找:
array:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第782行: 第655行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Dog.objects.filter(data__owner__other_pets__0__name='Fishy')
+
<syntaxhighlight lang="python">>>> Dog.objects.filter(data__owner__other_pets__0__name='Fishy')
&lt;QuerySet [&lt;Dog: Rufus&gt;]&gt;</pre>
+
<QuerySet [<Dog: Rufus>]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
If the key you wish to query by clashes with the name of another lookup, use
+
如果您希望查询的键与另一个查找的名称冲突,请改用 [[#id21|:lookup:`jsonfield.contains`]] 查找。
the [[#std-fieldlookup-jsonfield.contains|<code>jsonfield.contains</code>]] lookup instead.
 
  
If only one key or index is used, the SQL operator <code>-&gt;</code> is used. If multiple
+
如果仅使用一个键或索引,则使用 SQL 运算符 <code>-&gt;</code>。 如果使用多个运算符,则使用 <code>#&gt;</code> 运算符。
operators are used then the <code>#&gt;</code> operator is used.
 
  
To query for <code>null</code> in JSON data, use <code>None</code> as a value:
+
要在 JSON 数据中查询 <code>null</code>,请使用 <code>None</code> 作为值:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第800行: 第671行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Dog.objects.filter(data__owner=None)
+
<syntaxhighlight lang="python">>>> Dog.objects.filter(data__owner=None)
&lt;QuerySet [&lt;Dog: Meg&gt;]&gt;</pre>
+
<QuerySet [<Dog: Meg>]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
To query for missing keys, use the <code>isnull</code> lookup:
+
要查询丢失的键,请使用 <code>isnull</code> 查找:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第812行: 第683行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Dog.objects.create(name='Shep', data={'breed': 'collie'})
+
<syntaxhighlight lang="python">>>> Dog.objects.create(name='Shep', data={'breed': 'collie'})
&gt;&gt;&gt; Dog.objects.filter(data__owner__isnull=True)
+
>>> Dog.objects.filter(data__owner__isnull=True)
&lt;QuerySet [&lt;Dog: Shep&gt;]&gt;</pre>
+
<QuerySet [<Dog: Shep>]></syntaxhighlight>
  
 
</div>
 
</div>
第821行: 第692行:
 
<div class="versionchanged">
 
<div class="versionchanged">
  
In older versions, using <code>None</code> as a lookup value matches objects that
+
<span class="versionmodified changed"> 在 2.1 版更改: </span> 在旧版本中,使用 <code>None</code> 作为查找值匹配没有键的对象,而不是具有 <code>None</code> 键的对象价值。
don't have the key rather than objects that have the key with a <code>None</code>
 
value.
 
  
  
第831行: 第700行:
 
警告
 
警告
  
Since any string could be a key in a JSON object, any lookup other than
+
由于任何字符串都可能是 JSON 对象中的键,因此除下面列出的那些之外的任何查找都将被解释为键查找。 没有错误被提出。 输入错误时要格外小心,并始终检查您的查询是否按预期工作。
those listed below will be interpreted as a key lookup. No errors are
 
raised. Be extra careful for typing mistakes, and always check your queries
 
work as you intend.
 
  
  
第842行: 第708行:
 
<div id="containment-and-key-operations" class="section">
 
<div id="containment-and-key-operations" class="section">
  
==== Containment and key operations ====
+
==== 遏制和关键行动 ====
  
<span id="std-fieldlookup-jsonfield.contains" class="target"><span id="std:fieldlookup-jsonfield.contains"></span></span><span id="std-fieldlookup-jsonfield.contained_by" class="target"><span id="std:fieldlookup-jsonfield.contained_by"></span></span><span id="std-fieldlookup-jsonfield.has_key" class="target"><span id="std:fieldlookup-jsonfield.has_key"></span></span><span id="std-fieldlookup-jsonfield.has_any_keys" class="target"><span id="std:fieldlookup-jsonfield.has_any_keys"></span></span>
+
[[#django.contrib.postgres.fields.JSONField|JSONField]] [[#django.contrib.postgres.fields.HStoreField|HStoreField]] 共享与容器和密钥相关的查找。
<span id="std:fieldlookup-jsonfield.has_keys"></span>[[#django.contrib.postgres.fields.JSONField|<code>JSONField</code>]] shares lookups relating to
 
containment and keys with [[#django.contrib.postgres.fields.HStoreField|<code>HStoreField</code>]].
 
  
* [[#std-fieldlookup-hstorefield.contains|<code>contains</code>]] (accepts any JSON rather than just a dictionary of strings)
+
* [[#id23|:lookup:`包含 `]] (接受任何 JSON 而不仅仅是字符串字典)
* [[#std-fieldlookup-hstorefield.contained_by|<code>contained_by</code>]] (accepts any JSON rather than just a dictionary of strings)
+
* [[#id25|:lookup:`contained_by `]] (接受任何 JSON 而不仅仅是字符串字典)
* [[#std-fieldlookup-hstorefield.has_key|<code>has_key</code>]]
+
* [[#id27|<span id="id28" class="problematic">:lookup:`has_key `</span>]]
* [[#std-fieldlookup-hstorefield.has_any_keys|<code>has_any_keys</code>]]
+
* [[#id29|<span id="id30" class="problematic">:lookup:`has_any_keys `</span>]]
* [[#std-fieldlookup-hstorefield.has_keys|<code>has_keys</code>]]
+
* [[#id31|<span id="id32" class="problematic">:lookup:`has_keys `</span>]]
  
  
第862行: 第726行:
 
<div id="range-fields" class="section">
 
<div id="range-fields" class="section">
  
<span id="id3"></span>
+
<span id="id33"></span>
== Range Fields ==
+
== 范围字段 ==
  
There are five range field types, corresponding to the built-in range types in
+
有五种范围字段类型,对应于 PostgreSQL 中内置的范围类型。 这些字段用于存储一系列值; 例如事件的开始和结束时间戳,或活动适合的年龄范围。
PostgreSQL. These fields are used to store a range of values; for example the
 
start and end timestamps of an event, or the range of ages an activity is
 
suitable for.
 
  
All of the range fields translate to <span class="xref std std-ref">psycopg2 Range objects</span> in Python, but also accept tuples as input if no bounds
+
在 Python 中,所有范围字段都转换为 <span class="xref std std-ref">psycopg2 范围对象 </span>,但如果不需要边界信息,也可以接受元组作为输入。 默认包含下限,排除上限; 即,<code>[)</code>
information is necessary. The default is lower bound included, upper bound
 
excluded; that is, <code>[)</code>.
 
  
 
<div id="integerrangefield" class="section">
 
<div id="integerrangefield" class="section">
  
=== <code>IntegerRangeField</code> ===
+
=== IntegerRangeField ===
  
 
<dl>
 
<dl>
<dt>''class'' <code>IntegerRangeField</code><span class="sig-paren">(</span>''<span class="o">**</span><span class="n">options</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">IntegerRangeField</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">options</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Stores a range of integers. Based on an
+
<dd><p>存储一系列整数。 基于 [[../../../models/fields#django.db.models|IntegerField]]。 由数据库中的 <code>int4range</code> 和 Python 中的 <code>NumericRange</code> 表示。</p>
[[../../../models/fields#django.db.models|<code>IntegerField</code>]]. Represented by an <code>int4range</code> in
+
<p>无论保存数据时指定的边界如何,PostgreSQL 总是以规范的形式返回一个范围,该范围包括下限和不包括上限; 即 <code>[)</code></p></dd></dl>
the database and a <code>NumericRange</code> in
 
Python.</p>
 
<p>Regardless of the bounds specified when saving the data, PostgreSQL always
 
returns a range in a canonical form that includes the lower bound and
 
excludes the upper bound; that is <code>[)</code>.</p></dd></dl>
 
  
  
第892行: 第746行:
 
<div id="bigintegerrangefield" class="section">
 
<div id="bigintegerrangefield" class="section">
  
=== <code>BigIntegerRangeField</code> ===
+
=== BigIntegerRangeField ===
  
 
<dl>
 
<dl>
<dt>''class'' <code>BigIntegerRangeField</code><span class="sig-paren">(</span>''<span class="o">**</span><span class="n">options</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">BigIntegerRangeField</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">options</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Stores a range of large integers. Based on a
+
<dd><p>存储一系列大整数。 基于 [[../../../models/fields#django.db.models|BigIntegerField]]。 由数据库中的 <code>int8range</code> 和 Python 中的 <code>NumericRange</code> 表示。</p>
[[../../../models/fields#django.db.models|<code>BigIntegerField</code>]]. Represented by an <code>int8range</code>
+
<p>无论保存数据时指定的边界如何,PostgreSQL 总是以规范的形式返回一个范围,该范围包括下限和不包括上限; 即 <code>[)</code></p></dd></dl>
in the database and a <code>NumericRange</code> in
 
Python.</p>
 
<p>Regardless of the bounds specified when saving the data, PostgreSQL always
 
returns a range in a canonical form that includes the lower bound and
 
excludes the upper bound; that is <code>[)</code>.</p></dd></dl>
 
  
  
第908行: 第757行:
 
<div id="decimalrangefield" class="section">
 
<div id="decimalrangefield" class="section">
  
=== <code>DecimalRangeField</code> ===
+
=== DecimalRangeField ===
  
 
<dl>
 
<dl>
<dt>''class'' <code>DecimalRangeField</code><span class="sig-paren">(</span>''<span class="o">**</span><span class="n">options</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">DecimalRangeField</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">options</span></span>''<span class="sig-paren">)</span></dt>
 
<dd><div class="versionadded">
 
<dd><div class="versionadded">
  
 
+
<p><span class="versionmodified added">2.2 版中的新功能。</span></p>
  
 
</div>
 
</div>
<p>Stores a range of floating point values. Based on a
+
<p>存储一系列浮点值。 基于 [[../../../models/fields#django.db.models|DecimalField]]。 由数据库中的 <code>numrange</code> 和 Python 中的 <code>NumericRange</code> 表示。</p></dd></dl>
[[../../../models/fields#django.db.models|<code>DecimalField</code>]]. Represented by a <code>numrange</code> in
 
the database and a <code>NumericRange</code> in
 
Python.</p></dd></dl>
 
  
  
第926行: 第772行:
 
<div id="floatrangefield" class="section">
 
<div id="floatrangefield" class="section">
  
=== <code>FloatRangeField</code> ===
+
=== FloatRangeField ===
  
 
<dl>
 
<dl>
<dt>''class'' <code>FloatRangeField</code><span class="sig-paren">(</span>''<span class="o">**</span><span class="n">options</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">FloatRangeField</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">options</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Stores a range of floating point values. Based on a
+
<dd><p>存储一系列浮点值。 基于 [[../../../models/fields#django.db.models|FloatField]]。 由数据库中的 <code>numrange</code> 和 Python 中的 <code>NumericRange</code> 表示。</p>
[[../../../models/fields#django.db.models|<code>FloatField</code>]]. Represented by a <code>numrange</code> in the
 
database and a <code>NumericRange</code> in Python.</p>
 
 
<div class="deprecated">
 
<div class="deprecated">
  
<p><span class="versionmodified deprecated">2.2 版后已移除: </span>Use [[#django.contrib.postgres.fields.DecimalRangeField|<code>DecimalRangeField</code>]] instead.</p>
+
<p><span class="versionmodified deprecated"> 2.2 版起已弃用:</span> 改用 [[#django.contrib.postgres.fields.DecimalRangeField|DecimalRangeField]]</p>
  
 
</div></dd></dl>
 
</div></dd></dl>
第943行: 第787行:
 
<div id="datetimerangefield" class="section">
 
<div id="datetimerangefield" class="section">
  
=== <code>DateTimeRangeField</code> ===
+
=== DateTimeRangeField ===
  
; ''class'' <code>DateTimeRangeField</code><span class="sig-paren">(</span>''<span class="o">**</span><span class="n">options</span>''<span class="sig-paren">)</span>
+
; ''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">DateTimeRangeField</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">options</span></span>''<span class="sig-paren">)</span>
: Stores a range of timestamps. Based on a [[../../../models/fields#django.db.models|<code>DateTimeField</code>]]. Represented by a <code>tstzrange</code> in the database and a <code>DateTimeTZRange</code> in Python.
+
: 存储一系列时间戳。 基于 [[../../../models/fields#django.db.models|DateTimeField]]。 由数据库中的 <code>tstzrange</code> 和 Python 中的 <code>DateTimeTZRange</code> 表示。
  
  
第952行: 第796行:
 
<div id="daterangefield" class="section">
 
<div id="daterangefield" class="section">
  
=== <code>DateRangeField</code> ===
+
=== DateRangeField ===
  
 
<dl>
 
<dl>
<dt>''class'' <code>DateRangeField</code><span class="sig-paren">(</span>''<span class="o">**</span><span class="n">options</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">DateRangeField</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">options</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Stores a range of dates. Based on a
+
<dd><p>存储一系列日期。 基于 [[../../../models/fields#django.db.models|DateField]]。 由数据库中的 <code>daterange</code> 和 Python 中的 <code>DateRange</code> 表示。</p>
[[../../../models/fields#django.db.models|<code>DateField</code>]]. Represented by a <code>daterange</code> in the
+
<p>无论保存数据时指定的边界如何,PostgreSQL 总是以规范的形式返回一个范围,该范围包括下限和不包括上限; 即 <code>[)</code></p></dd></dl>
database and a <code>DateRange</code> in Python.</p>
 
<p>Regardless of the bounds specified when saving the data, PostgreSQL always
 
returns a range in a canonical form that includes the lower bound and
 
excludes the upper bound; that is <code>[)</code>.</p></dd></dl>
 
  
  
第967行: 第807行:
 
<div id="querying-range-fields" class="section">
 
<div id="querying-range-fields" class="section">
  
=== Querying Range Fields ===
+
=== 查询范围字段 ===
  
There are a number of custom lookups and transforms for range fields. They are
+
范围字段有许多自定义查找和转换。 它们可用于上述所有字段,但我们将使用以下示例模型:
available on all the above fields, but we will use the following example
 
model:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第977行: 第815行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.contrib.postgres.fields import IntegerRangeField
+
<syntaxhighlight lang="python">from django.contrib.postgres.fields import IntegerRangeField
 
from django.db import models
 
from django.db import models
  
第986行: 第824行:
  
 
     def __str__(self):
 
     def __str__(self):
         return self.name</pre>
+
         return self.name</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
We will also use the following example objects:
+
我们还将使用以下示例对象:
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第997行: 第835行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; import datetime
+
<syntaxhighlight lang="python">>>> import datetime
&gt;&gt;&gt; from django.utils import timezone
+
>>> from django.utils import timezone
&gt;&gt;&gt; now = timezone.now()
+
>>> now = timezone.now()
&gt;&gt;&gt; Event.objects.create(name='Soft play', ages=(0, 10), start=now)
+
>>> Event.objects.create(name='Soft play', ages=(0, 10), start=now)
&gt;&gt;&gt; Event.objects.create(name='Pub trip', ages=(21, None), start=now - datetime.timedelta(days=1))</pre>
+
>>> Event.objects.create(name='Pub trip', ages=(21, None), start=now - datetime.timedelta(days=1))</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
and <code>NumericRange</code>:
+
<code>NumericRange</code>
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,012行: 第850行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; from psycopg2.extras import NumericRange</pre>
+
<syntaxhighlight lang="python">>>> from psycopg2.extras import NumericRange</syntaxhighlight>
  
 
</div>
 
</div>
第1,019行: 第857行:
 
<div id="containment-functions" class="section">
 
<div id="containment-functions" class="section">
  
==== Containment functions ====
+
==== 包含函数 ====
  
As with other PostgreSQL fields, there are three standard containment
+
与其他 PostgreSQL 字段一样,有三个标准的包含运算符:<code>contains</code><code>contained_by</code> <code>overlap</code>,使用 SQL 运算符 <code>@&gt;</code><code>&lt;@</code> ] 和 <code>&amp;&amp;</code>
operators: <code>contains</code>, <code>contained_by</code> and <code>overlap</code>, using the SQL
 
operators <code>@&gt;</code>, <code>&lt;@</code>, and <code>&amp;&amp;</code> respectively.
 
  
<div id="std-fieldlookup-rangefield.contains" class="section">
+
<div id="id34" class="section">
  
<span id="std:fieldlookup-rangefield.contains"></span><span id="id4"></span>
+
===== contains =====
===== <code>contains</code> =====
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,034行: 第869行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Event.objects.filter(ages__contains=NumericRange(4, 5))
+
<syntaxhighlight lang="python">>>> Event.objects.filter(ages__contains=NumericRange(4, 5))
&lt;QuerySet [&lt;Event: Soft play&gt;]&gt;</pre>
+
<QuerySet [<Event: Soft play>]></syntaxhighlight>
  
 
</div>
 
</div>
第1,042行: 第877行:
  
 
</div>
 
</div>
<div id="std-fieldlookup-rangefield.contained_by" class="section">
+
<div id="id35" class="section">
  
<span id="std:fieldlookup-rangefield.contained_by"></span><span id="id5"></span>
+
===== contained_by =====
===== <code>contained_by</code> =====
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,051行: 第885行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Event.objects.filter(ages__contained_by=NumericRange(0, 15))
+
<syntaxhighlight lang="python">>>> Event.objects.filter(ages__contained_by=NumericRange(0, 15))
&lt;QuerySet [&lt;Event: Soft play&gt;]&gt;</pre>
+
<QuerySet [<Event: Soft play>]></syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The <code>contained_by</code> lookup is also available on the non-range field types:
+
<code>contained_by</code> 查找也可用于非范围字段类型:[[../../../models/fields#django.db.models|IntegerField]][[../../../models/fields#django.db.models|BigIntegerField]][[../../../models/fields#django.db.models|FloatField]][[../../../models/fields#django.db.models|DateField]] , [[../../../models/fields#django.db.models|DateTimeField]]。 例如:
[[../../../models/fields#django.db.models|<code>IntegerField</code>]],
 
[[../../../models/fields#django.db.models|<code>BigIntegerField</code>]],
 
[[../../../models/fields#django.db.models|<code>FloatField</code>]], [[../../../models/fields#django.db.models|<code>DateField</code>]],
 
and [[../../../models/fields#django.db.models|<code>DateTimeField</code>]]. For example:
 
  
 
<div class="highlight-default notranslate">
 
<div class="highlight-default notranslate">
第1,067行: 第897行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; from psycopg2.extras import DateTimeTZRange
+
<syntaxhighlight lang="python">>>> from psycopg2.extras import DateTimeTZRange
&gt;&gt;&gt; Event.objects.filter(start__contained_by=DateTimeTZRange(
+
>>> Event.objects.filter(start__contained_by=DateTimeTZRange(
 
...    timezone.now() - datetime.timedelta(hours=1),
 
...    timezone.now() - datetime.timedelta(hours=1),
 
...    timezone.now() + datetime.timedelta(hours=1),
 
...    timezone.now() + datetime.timedelta(hours=1),
 
... )
 
... )
&lt;QuerySet [&lt;Event: Soft play&gt;]&gt;</pre>
+
<QuerySet [<Event: Soft play>]></syntaxhighlight>
  
 
</div>
 
</div>
第1,079行: 第909行:
  
 
</div>
 
</div>
<div id="std-fieldlookup-rangefield.overlap" class="section">
+
<div id="id36" class="section">
  
<span id="std:fieldlookup-rangefield.overlap"></span><span id="id6"></span>
+
===== overlap =====
===== <code>overlap</code> =====
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,088行: 第917行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Event.objects.filter(ages__overlap=NumericRange(8, 12))
+
<syntaxhighlight lang="python">>>> Event.objects.filter(ages__overlap=NumericRange(8, 12))
&lt;QuerySet [&lt;Event: Soft play&gt;]&gt;</pre>
+
<QuerySet [<Event: Soft play>]></syntaxhighlight>
  
 
</div>
 
</div>
第1,100行: 第929行:
 
<div id="comparison-functions" class="section">
 
<div id="comparison-functions" class="section">
  
==== Comparison functions ====
+
==== 比较函数 ====
  
Range fields support the standard lookups: [[../../../models/querysets#std-fieldlookup-lt|<code>lt</code>]], [[../../../models/querysets#std-fieldlookup-gt|<code>gt</code>]],
+
范围字段支持标准查找: [[#id37|:lookup:`lt`]][[#id39|:lookup:`gt`]][[#id41|:lookup:`lte`]] [[#id43|:查找:`gte`]]。 这些不是特别有用 - 它们首先比较下限,然后仅在必要时比较上限。 这也是用于按范围字段排序的策略。 最好使用特定的范围比较运算符。
[[../../../models/querysets#std-fieldlookup-lte|<code>lte</code>]] and [[../../../models/querysets#std-fieldlookup-gte|<code>gte</code>]]. These are not particularly helpful - they
 
compare the lower bounds first and then the upper bounds only if necessary.
 
This is also the strategy used to order by a range field. It is better to use
 
the specific range comparison operators.
 
  
 
<div id="fully-lt" class="section">
 
<div id="fully-lt" class="section">
  
<span id="std-fieldlookup-rangefield.fully_lt"></span><span id="std:fieldlookup-rangefield.fully_lt"></span>
+
===== fully_lt =====
===== <code>fully_lt</code> =====
 
  
The returned ranges are strictly less than the passed range. In other words,
+
返回的范围严格小于传递的范围。 换句话说,返回范围内的所有点都小于传递范围内的所有点。
all the points in the returned range are less than all those in the passed
 
range.
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,121行: 第943行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Event.objects.filter(ages__fully_lt=NumericRange(11, 15))
+
<syntaxhighlight lang="python">>>> Event.objects.filter(ages__fully_lt=NumericRange(11, 15))
&lt;QuerySet [&lt;Event: Soft play&gt;]&gt;</pre>
+
<QuerySet [<Event: Soft play>]></syntaxhighlight>
  
 
</div>
 
</div>
第1,131行: 第953行:
 
<div id="fully-gt" class="section">
 
<div id="fully-gt" class="section">
  
<span id="std-fieldlookup-rangefield.fully_gt"></span><span id="std:fieldlookup-rangefield.fully_gt"></span>
+
===== fully_gt =====
===== <code>fully_gt</code> =====
 
  
The returned ranges are strictly greater than the passed range. In other words,
+
返回的范围严格大于传递的范围。 换句话说,返回范围内的所有点都大于传递范围内的所有点。
the all the points in the returned range are greater than all those in the
 
passed range.
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,142行: 第961行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Event.objects.filter(ages__fully_gt=NumericRange(11, 15))
+
<syntaxhighlight lang="python">>>> Event.objects.filter(ages__fully_gt=NumericRange(11, 15))
&lt;QuerySet [&lt;Event: Pub trip&gt;]&gt;</pre>
+
<QuerySet [<Event: Pub trip>]></syntaxhighlight>
  
 
</div>
 
</div>
第1,152行: 第971行:
 
<div id="not-lt" class="section">
 
<div id="not-lt" class="section">
  
<span id="std-fieldlookup-rangefield.not_lt"></span><span id="std:fieldlookup-rangefield.not_lt"></span>
+
===== not_lt =====
===== <code>not_lt</code> =====
 
  
The returned ranges do not contain any points less than the passed range, that
+
返回的范围不包含任何小于传入范围的点,即返回范围的下界至少是传入范围的下界。
is the lower bound of the returned range is at least the lower bound of the
 
passed range.
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,163行: 第979行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Event.objects.filter(ages__not_lt=NumericRange(0, 15))
+
<syntaxhighlight lang="python">>>> Event.objects.filter(ages__not_lt=NumericRange(0, 15))
&lt;QuerySet [&lt;Event: Soft play&gt;, &lt;Event: Pub trip&gt;]&gt;</pre>
+
<QuerySet [<Event: Soft play>, <Event: Pub trip>]></syntaxhighlight>
  
 
</div>
 
</div>
第1,173行: 第989行:
 
<div id="not-gt" class="section">
 
<div id="not-gt" class="section">
  
<span id="std-fieldlookup-rangefield.not_gt"></span><span id="std:fieldlookup-rangefield.not_gt"></span>
+
===== not_gt =====
===== <code>not_gt</code> =====
 
  
The returned ranges do not contain any points greater than the passed range, that
+
返回的范围不包含任何大于传入范围的点,也就是说,返回的范围的上界最多就是传入范围的上界。
is the upper bound of the returned range is at most the upper bound of the
 
passed range.
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,184行: 第997行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Event.objects.filter(ages__not_gt=NumericRange(3, 10))
+
<syntaxhighlight lang="python">>>> Event.objects.filter(ages__not_gt=NumericRange(3, 10))
&lt;QuerySet [&lt;Event: Soft play&gt;]&gt;</pre>
+
<QuerySet [<Event: Soft play>]></syntaxhighlight>
  
 
</div>
 
</div>
第1,194行: 第1,007行:
 
<div id="adjacent-to" class="section">
 
<div id="adjacent-to" class="section">
  
<span id="std-fieldlookup-rangefield.adjacent_to"></span><span id="std:fieldlookup-rangefield.adjacent_to"></span>
+
===== adjacent_to =====
===== <code>adjacent_to</code> =====
 
  
The returned ranges share a bound with the passed range.
+
返回的范围与传入的范围共享一个边界。
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,203行: 第1,015行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Event.objects.filter(ages__adjacent_to=NumericRange(10, 21))
+
<syntaxhighlight lang="python">>>> Event.objects.filter(ages__adjacent_to=NumericRange(10, 21))
&lt;QuerySet [&lt;Event: Soft play&gt;, &lt;Event: Pub trip&gt;]&gt;</pre>
+
<QuerySet [<Event: Soft play>, <Event: Pub trip>]></syntaxhighlight>
  
 
</div>
 
</div>
第1,215行: 第1,027行:
 
<div id="querying-using-the-bounds" class="section">
 
<div id="querying-using-the-bounds" class="section">
  
==== Querying using the bounds ====
+
==== 使用边界进行查询 ====
  
There are three transforms available for use in queries. You can extract the
+
有三种转换可用于查询。 您可以提取下限或上限,或根据空值进行查询。
lower or upper bound, or query based on emptiness.
 
  
 
<div id="startswith" class="section">
 
<div id="startswith" class="section">
  
<span id="std-fieldlookup-rangefield.startswith"></span><span id="std:fieldlookup-rangefield.startswith"></span>
+
===== startswith =====
===== <code>startswith</code> =====
 
  
Returned objects have the given lower bound. Can be chained to valid lookups
+
返回的对象具有给定的下限。 可以链接到基本字段的有效查找。
for the base field.
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,232行: 第1,041行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Event.objects.filter(ages__startswith=21)
+
<syntaxhighlight lang="python">>>> Event.objects.filter(ages__startswith=21)
&lt;QuerySet [&lt;Event: Pub trip&gt;]&gt;</pre>
+
<QuerySet [<Event: Pub trip>]></syntaxhighlight>
  
 
</div>
 
</div>
第1,242行: 第1,051行:
 
<div id="endswith" class="section">
 
<div id="endswith" class="section">
  
<span id="std-fieldlookup-rangefield.endswith"></span><span id="std:fieldlookup-rangefield.endswith"></span>
+
===== endswith =====
===== <code>endswith</code> =====
 
  
Returned objects have the given upper bound. Can be chained to valid lookups
+
返回的对象具有给定的上限。 可以链接到基本字段的有效查找。
for the base field.
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,252行: 第1,059行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Event.objects.filter(ages__endswith=10)
+
<syntaxhighlight lang="python">>>> Event.objects.filter(ages__endswith=10)
&lt;QuerySet [&lt;Event: Soft play&gt;]&gt;</pre>
+
<QuerySet [<Event: Soft play>]></syntaxhighlight>
  
 
</div>
 
</div>
第1,262行: 第1,069行:
 
<div id="isempty" class="section">
 
<div id="isempty" class="section">
  
<span id="std-fieldlookup-rangefield.isempty"></span><span id="std:fieldlookup-rangefield.isempty"></span>
+
===== isempty =====
===== <code>isempty</code> =====
 
  
Returned objects are empty ranges. Can be chained to valid lookups for a
+
返回的对象是空范围。 可以链接到 [[../../../models/fields#django.db.models|BooleanField]] 的有效查找。
[[../../../models/fields#django.db.models|<code>BooleanField</code>]].
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第1,272行: 第1,077行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; Event.objects.filter(ages__isempty=True)
+
<syntaxhighlight lang="python">>>> Event.objects.filter(ages__isempty=True)
&lt;QuerySet []&gt;</pre>
+
<QuerySet []></syntaxhighlight>
  
 
</div>
 
</div>
第1,286行: 第1,091行:
 
<div id="defining-your-own-range-types" class="section">
 
<div id="defining-your-own-range-types" class="section">
  
=== Defining your own range types ===
+
=== 定义自己的范围类型 ===
  
PostgreSQL allows the definition of custom range types. Django's model and form
+
PostgreSQL 允许定义自定义范围类型。 Django 的模型和表单字段实现使用下面的基类,并且 psycopg2 提供了 <code>register_range()</code> 以允许使用自定义范围类型。
field implementations use base classes below, and psycopg2 provides a
 
<code>register_range()</code> to allow use of custom range
 
types.
 
  
 
<dl>
 
<dl>
<dt>''class'' <code>RangeField</code><span class="sig-paren">(</span>''<span class="o">**</span><span class="n">options</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-name descname"><span class="pre">RangeField</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">options</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Base class for model range fields.</p>
+
<dd><p>模型范围字段的基类。</p>
 
<dl>
 
<dl>
<dt><code>base_field</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">base_field</span></span></dt>
<dd><p>The model field class to use.</p></dd></dl>
+
<dd><p>要使用的模型字段类。</p></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>range_type</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">range_type</span></span></dt>
<dd><p>The psycopg2 range type to use.</p></dd></dl>
+
<dd><p>要使用的 psycopg2 范围类型。</p></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>form_field</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">form_field</span></span></dt>
<dd><p>The form field class to use. Should be a subclass of
+
<dd><p>要使用的表单字段类。 应该是 [[#django.contrib.postgres.fields.django.contrib.postgres.forms.BaseRangeField|django.contrib.postgres.forms.BaseRangeField]] 的子类。</p></dd></dl>
[[#django.contrib.postgres.fields.django.contrib.postgres.forms.BaseRangeField|<code>django.contrib.postgres.forms.BaseRangeField</code>]].</p></dd></dl>
 
 
</dd></dl>
 
</dd></dl>
  
 
<dl>
 
<dl>
<dt>''class'' <code>django.contrib.postgres.forms.</code><code>BaseRangeField</code></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">django.contrib.postgres.forms.</span></span><span class="sig-name descname"><span class="pre">BaseRangeField</span></span></dt>
<dd><p>Base class for form range fields.</p>
+
<dd><p>表范围字段的基类。</p>
 
<dl>
 
<dl>
<dt><code>base_field</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">base_field</span></span></dt>
<dd><p>The form field to use.</p></dd></dl>
+
<dd><p>要使用的表字段。</p></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>range_type</code></dt>
+
<dt><span class="sig-name descname"><span class="pre">range_type</span></span></dt>
<dd><p>The psycopg2 range type to use.</p></dd></dl>
+
<dd><p>要使用的 psycopg2 范围类型。</p></dd></dl>
 
</dd></dl>
 
</dd></dl>
  
第1,326行: 第1,127行:
  
 
</div>
 
</div>
 +
 +
</div>
 +
<div class="clearer">
 +
 +
  
 
</div>
 
</div>
  
[[Category:Django 2.2.x 中文文档]]
+
[[Category:Django 2.2.x 文档]]

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

PostgreSQL 特有模型字段

所有这些字段都可以从 django.contrib.postgres.fields 模块获得。

对这些字段进行索引

IndexField.db_index 都创建了 B 树索引,这在查询复杂数据类型时不是特别有用。 GinIndexGistIndex 等索引更适合,尽管索引选择取决于您使用的查询。 通常,对于 范围字段HStoreField,GiST 可能是一个不错的选择,而 GIN 可能对 ArrayFieldJSONField 有帮助。


ArrayField

class ArrayField(base_field, size=None, **options)

用于存储数据列表的字段。 大多数字段类型都可以使用,您只需将另一个字段实例作为 base_field 传递。 您还可以指定 大小ArrayField 可以嵌套存储多维数组。

如果您为该字段指定 default,请确保它是一个可调用对象,例如 list(对于一个空的默认值)或一个返回列表的可调用对象(例如一个函数)。 不正确地使用 default=[] 会创建一个可变默认值,该默认值在 ArrayField 的所有实例之间共享。

base_field

这是一个必要的参数。

指定数组的基础数据类型和行为。 它应该是 Field 子类的一个实例。 例如,它可以是 IntegerFieldCharField。 大多数字段类型都是允许的,但处理关系数据的字段类型除外(ForeignKeyOneToOneFieldManyToManyField)。

可以嵌套数组字段 - 您可以将 ArrayField 的实例指定为 base_field。 例如:

from django.contrib.postgres.fields import ArrayField
from django.db import models

class ChessBoard(models.Model):
    board = ArrayField(
        ArrayField(
            models.CharField(max_length=10, blank=True),
            size=8,
        ),
        size=8,
    )

数据库和模型之间的值的转换、数据和配置的验证以及序列化都是委托给底层基础字段的。

size

这是一个可选的参数。

如果通过,数组将具有指定的最大大小。 这将传递给数据库,尽管 PostgreSQL 目前没有强制执行此限制。

笔记

嵌套 ArrayField 时,无论是否使用 size 参数,PostgreSQL 都要求数组为矩形:

from django.contrib.postgres.fields import ArrayField
from django.db import models

class Board(models.Model):
    pieces = ArrayField(ArrayField(models.IntegerField()))

# Valid
Board(pieces=[
    [2, 3],
    [2, 1],
])

# Not valid
Board(pieces=[
    [2, 3],
    [2],
])

如果需要不规则的形状,那么底层字段应该可以为空,并且值用 None 填充。


查询ArrayField

ArrayField 有许多自定义查找和转换。 我们将使用以下示例模型:

from django.contrib.postgres.fields import ArrayField
from django.db import models

class Post(models.Model):
    name = models.CharField(max_length=200)
    tags = ArrayField(models.CharField(max_length=200), blank=True)

    def __str__(self):
        return self.name

contains

:lookup:`contains` 查找在 ArrayField 上被覆盖。 返回的对象将是那些传递的值是数据子集的对象。 它使用 SQL 运算符 @>。 例如:

>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
>>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])

>>> Post.objects.filter(tags__contains=['thoughts'])
<QuerySet [<Post: First post>, <Post: Second post>]>

>>> Post.objects.filter(tags__contains=['django'])
<QuerySet [<Post: First post>, <Post: Third post>]>

>>> Post.objects.filter(tags__contains=['django', 'thoughts'])
<QuerySet [<Post: First post>]>

contained_by

这是相反的 :lookup:`包含 ` 查找 - 返回的对象将是那些数据是传递值的子集的对象。 它使用 SQL 运算符 <@。 例如:

>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
>>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])

>>> Post.objects.filter(tags__contained_by=['thoughts', 'django'])
<QuerySet [<Post: First post>, <Post: Second post>]>

>>> Post.objects.filter(tags__contained_by=['thoughts', 'django', 'tutorial'])
<QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>

overlap

返回数据与传递的值共享任何结果的对象。 使用 SQL 运算符 &&。 例如:

>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
>>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])

>>> Post.objects.filter(tags__overlap=['thoughts'])
<QuerySet [<Post: First post>, <Post: Second post>]>

>>> Post.objects.filter(tags__overlap=['thoughts', 'tutorial'])
<QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>

len

返回数组的长度。 之后可用的查找是可用于 IntegerField 的那些。 例如:

>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])

>>> Post.objects.filter(tags__len=1)
<QuerySet [<Post: Second post>]>

索引转换

索引将索引转换为数组。 可以使用任何非负整数。 如果超过数组的 大小 ,则没有错误。 转换后可用的查找来自 base_field。 例如:

>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])

>>> Post.objects.filter(tags__0='thoughts')
<QuerySet [<Post: First post>, <Post: Second post>]>

>>> Post.objects.filter(tags__1__iexact='Django')
<QuerySet [<Post: First post>]>

>>> Post.objects.filter(tags__276='javascript')
<QuerySet []>

笔记

PostgreSQL 在编写原始 SQL 时对数组字段使用基于 1 的索引。 然而,这些索引和那些用于 :lookup:`切片 ` 使用基于 0 的索引以与 Python 保持一致。


切片转换

切片变换采用数组的切片。 可以使用任何两个非负整数,用单个下划线分隔。 转换后可用的查找不会改变。 例如:

>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
>>> Post.objects.create(name='Third post', tags=['django', 'python', 'thoughts'])

>>> Post.objects.filter(tags__0_1=['thoughts'])
<QuerySet [<Post: First post>, <Post: Second post>]>

>>> Post.objects.filter(tags__0_2__contains=['thoughts'])
<QuerySet [<Post: First post>, <Post: Second post>]>

笔记

PostgreSQL 在编写原始 SQL 时对数组字段使用基于 1 的索引。 然而,这些切片和那些用于 :lookup:`索引 ` 使用基于 0 的索引以与 Python 保持一致。


带索引和切片的多维数组

在多维数组上使用索引和切片时,PostgreSQL 有一些相当深奥的行为。 使用索引来深入到最终的底层数据总是有效的,但大多数其他切片在数据库级别的行为很奇怪,并且无法以逻辑一致的方式被 Django 支持。


CIText 字段

class CIText(**options)

创建由 citext 类型支持的不区分大小写的文本字段的 mixin。 在使用之前阅读 性能注意事项

要使用citext,在第一次CreateModel迁移操作之前,使用CITextExtension操作在PostgreSQL中设置citext扩展

如果您使用 CIText 字段的 ArrayField,则必须在 :setting:`INSTALLED_APPS` 中添加 'django.contrib.postgres',否则字段值将显示为类似 '{thoughts,django}' 的字符串。

提供了几个使用混入的字段:

class CICharField(**options)
class CIEmailField(**options)
class CITextField(**options)

这些字段分别是 CharFieldEmailFieldTextField 的子类。

max_length 不会在数据库中强制执行,因为 citext 的行为类似于 PostgreSQL 的 text 类型。


HStoreField

class HStoreField(**options)

用于存储键值对的字段。 使用的 Python 数据类型是 dict。 键必须是字符串,值可以是字符串或空值(Python 中的 None)。

要使用此字段,您需要:

  1. 在您的 :setting:`INSTALLED_APPS` 中添加 'django.contrib.postgres'

  2. 在PostgreSQL中设置hstore扩展

如果您跳过第一步,您将看到类似 can't adapt type 'dict' 的错误,如果您跳过第二步,则会看到 type "hstore" does not exist 之类的错误。

笔记

有时,要求或限制对给定字段有效的键可能很有用。 这可以使用 KeysValidator 来完成。


查询HStoreField

除了按键查询的能力外,还有许多可用于 HStoreField 的自定义查找。

我们将使用以下示例模型:

from django.contrib.postgres.fields import HStoreField
from django.db import models

class Dog(models.Model):
    name = models.CharField(max_length=200)
    data = HStoreField()

    def __str__(self):
        return self.name

键查找

要基于给定的键进行查询,您只需使用该键作为查找名称:

>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie'})

>>> Dog.objects.filter(data__breed='collie')
<QuerySet [<Dog: Meg>]>

您可以在键查找后链接其他查找:

>>> Dog.objects.filter(data__breed__contains='l')
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>

如果您希望查询的键与另一个查找的名称发生冲突,您需要改用 :lookup:`hstorefield.contains` 查找。

警告

由于任何字符串都可以是 hstore 值中的键,因此除下面列出的那些之外的任何查找都将被解释为键查找。 没有错误被提出。 输入错误时要格外小心,并始终检查您的查询是否按预期工作。


contains

:lookup:`contains` 查找在 HStoreField 上被覆盖。 返回的对象是那些给定的 dict 键值对都包含在字段中的对象。 它使用 SQL 运算符 @>。 例如:

>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
>>> Dog.objects.create(name='Fred', data={})

>>> Dog.objects.filter(data__contains={'owner': 'Bob'})
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>

>>> Dog.objects.filter(data__contains={'breed': 'collie'})
<QuerySet [<Dog: Meg>]>

contained_by

这是相反的 :lookup:`包含 ` 查找 - 返回的对象将是那些对象上的键值对是传递值中键值对的子集的对象。 它使用 SQL 运算符 <@。 例如:

>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
>>> Dog.objects.create(name='Fred', data={})

>>> Dog.objects.filter(data__contained_by={'breed': 'collie', 'owner': 'Bob'})
<QuerySet [<Dog: Meg>, <Dog: Fred>]>

>>> Dog.objects.filter(data__contained_by={'breed': 'collie'})
<QuerySet [<Dog: Fred>]>

has_key

返回给定键在数据中的对象。 使用 SQL 运算符 ?。 例如:

>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})

>>> Dog.objects.filter(data__has_key='owner')
<QuerySet [<Dog: Meg>]>

has_any_keys

返回任何给定键在数据中的对象。 使用 SQL 运算符 ?|。 例如:

>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
>>> Dog.objects.create(name='Meg', data={'owner': 'Bob'})
>>> Dog.objects.create(name='Fred', data={})

>>> Dog.objects.filter(data__has_any_keys=['owner', 'breed'])
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>

has_keys

返回所有给定键都在数据中的对象。 使用 SQL 运算符 ?&。 例如:

>>> Dog.objects.create(name='Rufus', data={})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})

>>> Dog.objects.filter(data__has_keys=['breed', 'owner'])
<QuerySet [<Dog: Meg>]>

keys

返回键数组为给定值的对象。 请注意,不能保证顺序是可靠的,因此此转换主要用于与 ArrayField 上的查找结合使用。 使用 SQL 函数 akeys()。 例如:

>>> Dog.objects.create(name='Rufus', data={'toy': 'bone'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})

>>> Dog.objects.filter(data__keys__overlap=['breed', 'toy'])
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>

values

返回值数组是给定值的对象。 请注意,不能保证顺序是可靠的,因此此转换主要用于与 ArrayField 上的查找结合使用。 使用 SQL 函数 avalues()。 例如:

>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})

>>> Dog.objects.filter(data__values__contains=['collie'])
<QuerySet [<Dog: Meg>]>

JSONField

class JSONField(encoder=None, **options)

用于存储 JSON 编码数据的字段。 在 Python 中,数据以其 Python 原生格式表示:字典、列表、字符串、数字、布尔值和 None

encoder

一个可选的 JSON 编码类,用于序列化标准 JSON 序列化程序(datetimeuuid 等)不支持的数据类型。 例如,您可以使用 DjangoJSONEncoder 类或任何其他 json.JSONEncoder 子类。

从数据库中检索值时,它将采用自定义编码器选择的格式(通常是字符串),因此您需要采取额外的步骤将值转换回初始数据类型 ( Model.from_db()Field.from_db_value() 是用于此目的的两个可能的钩子)。 您的反序列化可能需要考虑到您无法确定输入类型的事实。 例如,您冒着返回 datetime 的风险,该字符串实际上是一个恰好与为 datetime 选择的格式相同的字符串。

如果你给这个字段一个 default,确保它是一个可调用的,比如 dict(对于一个空的默认值)或一个返回一个字典的可调用的(比如一个函数)。 不正确地使用 default={} 会创建一个可变默认值,该默认值在 JSONField 的所有实例之间共享。

笔记

PostgreSQL 有两种基于 JSON 的原生数据类型:jsonjsonb。 它们之间的主要区别在于它们的存储方式和查询方式。 PostgreSQL 的 json 字段存储为 JSON 的原始字符串表示形式,并且必须在基于键查询时即时解码。 jsonb 字段基于允许索引的 JSON 的实际结构进行存储。 权衡是写入 jsonb 字段的少量额外成本。 JSONField 使用 jsonb


查询JSONField

我们将使用以下示例模型:

from django.contrib.postgres.fields import JSONField
from django.db import models

class Dog(models.Model):
    name = models.CharField(max_length=200)
    data = JSONField()

    def __str__(self):
        return self.name

键、索引和路径查找

要基于给定的字典键进行查询,只需使用该键作为查找名称:

>>> Dog.objects.create(name='Rufus', data={
...     'breed': 'labrador',
...     'owner': {
...         'name': 'Bob',
...         'other_pets': [{
...             'name': 'Fishy',
...         }],
...     },
... })
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': None})

>>> Dog.objects.filter(data__breed='collie')
<QuerySet [<Dog: Meg>]>

多个键可以链接在一起以形成路径查找:

>>> Dog.objects.filter(data__owner__name='Bob')
<QuerySet [<Dog: Rufus>]>

如果键是整数,它将被解释为数组中的索引查找:

>>> Dog.objects.filter(data__owner__other_pets__0__name='Fishy')
<QuerySet [<Dog: Rufus>]>

如果您希望查询的键与另一个查找的名称冲突,请改用 :lookup:`jsonfield.contains` 查找。

如果仅使用一个键或索引,则使用 SQL 运算符 ->。 如果使用多个运算符,则使用 #> 运算符。

要在 JSON 数据中查询 null,请使用 None 作为值:

>>> Dog.objects.filter(data__owner=None)
<QuerySet [<Dog: Meg>]>

要查询丢失的键,请使用 isnull 查找:

>>> Dog.objects.create(name='Shep', data={'breed': 'collie'})
>>> Dog.objects.filter(data__owner__isnull=True)
<QuerySet [<Dog: Shep>]>

在 2.1 版更改: 在旧版本中,使用 None 作为查找值匹配没有键的对象,而不是具有 None 键的对象价值。


警告

由于任何字符串都可能是 JSON 对象中的键,因此除下面列出的那些之外的任何查找都将被解释为键查找。 没有错误被提出。 输入错误时要格外小心,并始终检查您的查询是否按预期工作。


遏制和关键行动

JSONFieldHStoreField 共享与容器和密钥相关的查找。


范围字段

有五种范围字段类型,对应于 PostgreSQL 中内置的范围类型。 这些字段用于存储一系列值; 例如事件的开始和结束时间戳,或活动适合的年龄范围。

在 Python 中,所有范围字段都转换为 psycopg2 范围对象 ,但如果不需要边界信息,也可以接受元组作为输入。 默认包含下限,排除上限; 即,[)

IntegerRangeField

class IntegerRangeField(**options)

存储一系列整数。 基于 IntegerField。 由数据库中的 int4range 和 Python 中的 NumericRange 表示。

无论保存数据时指定的边界如何,PostgreSQL 总是以规范的形式返回一个范围,该范围包括下限和不包括上限; 即 [)


BigIntegerRangeField

class BigIntegerRangeField(**options)

存储一系列大整数。 基于 BigIntegerField。 由数据库中的 int8range 和 Python 中的 NumericRange 表示。

无论保存数据时指定的边界如何,PostgreSQL 总是以规范的形式返回一个范围,该范围包括下限和不包括上限; 即 [)


DecimalRangeField

class DecimalRangeField(**options)

2.2 版中的新功能。

存储一系列浮点值。 基于 DecimalField。 由数据库中的 numrange 和 Python 中的 NumericRange 表示。


FloatRangeField

class FloatRangeField(**options)

存储一系列浮点值。 基于 FloatField。 由数据库中的 numrange 和 Python 中的 NumericRange 表示。

自 2.2 版起已弃用: 改用 DecimalRangeField


DateTimeRangeField

class DateTimeRangeField(**options)
存储一系列时间戳。 基于 DateTimeField。 由数据库中的 tstzrange 和 Python 中的 DateTimeTZRange 表示。


DateRangeField

class DateRangeField(**options)

存储一系列日期。 基于 DateField。 由数据库中的 daterange 和 Python 中的 DateRange 表示。

无论保存数据时指定的边界如何,PostgreSQL 总是以规范的形式返回一个范围,该范围包括下限和不包括上限; 即 [)


查询范围字段

范围字段有许多自定义查找和转换。 它们可用于上述所有字段,但我们将使用以下示例模型:

from django.contrib.postgres.fields import IntegerRangeField
from django.db import models

class Event(models.Model):
    name = models.CharField(max_length=200)
    ages = IntegerRangeField()
    start = models.DateTimeField()

    def __str__(self):
        return self.name

我们还将使用以下示例对象:

>>> import datetime
>>> from django.utils import timezone
>>> now = timezone.now()
>>> Event.objects.create(name='Soft play', ages=(0, 10), start=now)
>>> Event.objects.create(name='Pub trip', ages=(21, None), start=now - datetime.timedelta(days=1))

NumericRange

>>> from psycopg2.extras import NumericRange

包含函数

与其他 PostgreSQL 字段一样,有三个标准的包含运算符:containscontained_byoverlap,使用 SQL 运算符 @><@ ] 和 &&

contains
>>> Event.objects.filter(ages__contains=NumericRange(4, 5))
<QuerySet [<Event: Soft play>]>
contained_by
>>> Event.objects.filter(ages__contained_by=NumericRange(0, 15))
<QuerySet [<Event: Soft play>]>

contained_by 查找也可用于非范围字段类型:IntegerFieldBigIntegerFieldFloatFieldDateField , 和 DateTimeField。 例如:

>>> from psycopg2.extras import DateTimeTZRange
>>> Event.objects.filter(start__contained_by=DateTimeTZRange(
...     timezone.now() - datetime.timedelta(hours=1),
...     timezone.now() + datetime.timedelta(hours=1),
... )
<QuerySet [<Event: Soft play>]>
overlap
>>> Event.objects.filter(ages__overlap=NumericRange(8, 12))
<QuerySet [<Event: Soft play>]>

比较函数

范围字段支持标准查找: :lookup:`lt`:lookup:`gt`:lookup:`lte`:查找:`gte`。 这些不是特别有用 - 它们首先比较下限,然后仅在必要时比较上限。 这也是用于按范围字段排序的策略。 最好使用特定的范围比较运算符。

fully_lt

返回的范围严格小于传递的范围。 换句话说,返回范围内的所有点都小于传递范围内的所有点。

>>> Event.objects.filter(ages__fully_lt=NumericRange(11, 15))
<QuerySet [<Event: Soft play>]>
fully_gt

返回的范围严格大于传递的范围。 换句话说,返回范围内的所有点都大于传递范围内的所有点。

>>> Event.objects.filter(ages__fully_gt=NumericRange(11, 15))
<QuerySet [<Event: Pub trip>]>
not_lt

返回的范围不包含任何小于传入范围的点,即返回范围的下界至少是传入范围的下界。

>>> Event.objects.filter(ages__not_lt=NumericRange(0, 15))
<QuerySet [<Event: Soft play>, <Event: Pub trip>]>
not_gt

返回的范围不包含任何大于传入范围的点,也就是说,返回的范围的上界最多就是传入范围的上界。

>>> Event.objects.filter(ages__not_gt=NumericRange(3, 10))
<QuerySet [<Event: Soft play>]>
adjacent_to

返回的范围与传入的范围共享一个边界。

>>> Event.objects.filter(ages__adjacent_to=NumericRange(10, 21))
<QuerySet [<Event: Soft play>, <Event: Pub trip>]>

使用边界进行查询

有三种转换可用于查询。 您可以提取下限或上限,或根据空值进行查询。

startswith

返回的对象具有给定的下限。 可以链接到基本字段的有效查找。

>>> Event.objects.filter(ages__startswith=21)
<QuerySet [<Event: Pub trip>]>
endswith

返回的对象具有给定的上限。 可以链接到基本字段的有效查找。

>>> Event.objects.filter(ages__endswith=10)
<QuerySet [<Event: Soft play>]>
isempty

返回的对象是空范围。 可以链接到 BooleanField 的有效查找。

>>> Event.objects.filter(ages__isempty=True)
<QuerySet []>

定义自己的范围类型

PostgreSQL 允许定义自定义范围类型。 Django 的模型和表单字段实现使用下面的基类,并且 psycopg2 提供了 register_range() 以允许使用自定义范围类型。

class RangeField(**options)

模型范围字段的基类。

base_field

要使用的模型字段类。

range_type

要使用的 psycopg2 范围类型。

form_field

要使用的表单字段类。 应该是 django.contrib.postgres.forms.BaseRangeField 的子类。

class django.contrib.postgres.forms.BaseRangeField

表范围字段的基类。

base_field

要使用的表字段。

range_type

要使用的 psycopg2 范围类型。