1. ================================
    
  2. PostgreSQL specific model fields
    
  3. ================================
    
  4. 
    
  5. All of these fields are available from the ``django.contrib.postgres.fields``
    
  6. module.
    
  7. 
    
  8. .. currentmodule:: django.contrib.postgres.fields
    
  9. 
    
  10. Indexing these fields
    
  11. =====================
    
  12. 
    
  13. :class:`~django.db.models.Index` and :attr:`.Field.db_index` both create a
    
  14. B-tree index, which isn't particularly helpful when querying complex data types.
    
  15. Indexes such as :class:`~django.contrib.postgres.indexes.GinIndex` and
    
  16. :class:`~django.contrib.postgres.indexes.GistIndex` are better suited, though
    
  17. the index choice is dependent on the queries that you're using. Generally, GiST
    
  18. may be a good choice for the :ref:`range fields <range-fields>` and
    
  19. :class:`HStoreField`, and GIN may be helpful for :class:`ArrayField`.
    
  20. 
    
  21. ``ArrayField``
    
  22. ==============
    
  23. 
    
  24. .. class:: ArrayField(base_field, size=None, **options)
    
  25. 
    
  26.     A field for storing lists of data. Most field types can be used, and you
    
  27.     pass another field instance as the :attr:`base_field
    
  28.     <ArrayField.base_field>`. You may also specify a :attr:`size
    
  29.     <ArrayField.size>`. ``ArrayField`` can be nested to store multi-dimensional
    
  30.     arrays.
    
  31. 
    
  32.     If you give the field a :attr:`~django.db.models.Field.default`, ensure
    
  33.     it's a callable such as ``list`` (for an empty default) or a callable that
    
  34.     returns a list (such as a function). Incorrectly using ``default=[]``
    
  35.     creates a mutable default that is shared between all instances of
    
  36.     ``ArrayField``.
    
  37. 
    
  38.     .. attribute:: base_field
    
  39. 
    
  40.         This is a required argument.
    
  41. 
    
  42.         Specifies the underlying data type and behavior for the array. It
    
  43.         should be an instance of a subclass of
    
  44.         :class:`~django.db.models.Field`. For example, it could be an
    
  45.         :class:`~django.db.models.IntegerField` or a
    
  46.         :class:`~django.db.models.CharField`. Most field types are permitted,
    
  47.         with the exception of those handling relational data
    
  48.         (:class:`~django.db.models.ForeignKey`,
    
  49.         :class:`~django.db.models.OneToOneField` and
    
  50.         :class:`~django.db.models.ManyToManyField`) and file fields (
    
  51.         :class:`~django.db.models.FileField` and
    
  52.         :class:`~django.db.models.ImageField`).
    
  53. 
    
  54.         It is possible to nest array fields - you can specify an instance of
    
  55.         ``ArrayField`` as the ``base_field``. For example::
    
  56. 
    
  57.             from django.contrib.postgres.fields import ArrayField
    
  58.             from django.db import models
    
  59. 
    
  60.             class ChessBoard(models.Model):
    
  61.                 board = ArrayField(
    
  62.                     ArrayField(
    
  63.                         models.CharField(max_length=10, blank=True),
    
  64.                         size=8,
    
  65.                     ),
    
  66.                     size=8,
    
  67.                 )
    
  68. 
    
  69.         Transformation of values between the database and the model, validation
    
  70.         of data and configuration, and serialization are all delegated to the
    
  71.         underlying base field.
    
  72. 
    
  73.     .. attribute:: size
    
  74. 
    
  75.         This is an optional argument.
    
  76. 
    
  77.         If passed, the array will have a maximum size as specified. This will
    
  78.         be passed to the database, although PostgreSQL at present does not
    
  79.         enforce the restriction.
    
  80. 
    
  81. .. note::
    
  82. 
    
  83.     When nesting ``ArrayField``, whether you use the ``size`` parameter or not,
    
  84.     PostgreSQL requires that the arrays are rectangular::
    
  85. 
    
  86.         from django.contrib.postgres.fields import ArrayField
    
  87.         from django.db import models
    
  88. 
    
  89.         class Board(models.Model):
    
  90.             pieces = ArrayField(ArrayField(models.IntegerField()))
    
  91. 
    
  92.         # Valid
    
  93.         Board(pieces=[
    
  94.             [2, 3],
    
  95.             [2, 1],
    
  96.         ])
    
  97. 
    
  98.         # Not valid
    
  99.         Board(pieces=[
    
  100.             [2, 3],
    
  101.             [2],
    
  102.         ])
    
  103. 
    
  104.     If irregular shapes are required, then the underlying field should be made
    
  105.     nullable and the values padded with ``None``.
    
  106. 
    
  107. Querying ``ArrayField``
    
  108. -----------------------
    
  109. 
    
  110. There are a number of custom lookups and transforms for :class:`ArrayField`.
    
  111. We will use the following example model::
    
  112. 
    
  113.     from django.contrib.postgres.fields import ArrayField
    
  114.     from django.db import models
    
  115. 
    
  116.     class Post(models.Model):
    
  117.         name = models.CharField(max_length=200)
    
  118.         tags = ArrayField(models.CharField(max_length=200), blank=True)
    
  119. 
    
  120.         def __str__(self):
    
  121.             return self.name
    
  122. 
    
  123. .. fieldlookup:: arrayfield.contains
    
  124. 
    
  125. ``contains``
    
  126. ~~~~~~~~~~~~
    
  127. 
    
  128. The :lookup:`contains` lookup is overridden on :class:`ArrayField`. The
    
  129. returned objects will be those where the values passed are a subset of the
    
  130. data. It uses the SQL operator ``@>``. For example::
    
  131. 
    
  132.     >>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
    
  133.     >>> Post.objects.create(name='Second post', tags=['thoughts'])
    
  134.     >>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])
    
  135. 
    
  136.     >>> Post.objects.filter(tags__contains=['thoughts'])
    
  137.     <QuerySet [<Post: First post>, <Post: Second post>]>
    
  138. 
    
  139.     >>> Post.objects.filter(tags__contains=['django'])
    
  140.     <QuerySet [<Post: First post>, <Post: Third post>]>
    
  141. 
    
  142.     >>> Post.objects.filter(tags__contains=['django', 'thoughts'])
    
  143.     <QuerySet [<Post: First post>]>
    
  144. 
    
  145. .. fieldlookup:: arrayfield.contained_by
    
  146. 
    
  147. ``contained_by``
    
  148. ~~~~~~~~~~~~~~~~
    
  149. 
    
  150. This is the inverse of the :lookup:`contains <arrayfield.contains>` lookup -
    
  151. the objects returned will be those where the data is a subset of the values
    
  152. passed. It uses the SQL operator ``<@``. For example::
    
  153. 
    
  154.     >>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
    
  155.     >>> Post.objects.create(name='Second post', tags=['thoughts'])
    
  156.     >>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])
    
  157. 
    
  158.     >>> Post.objects.filter(tags__contained_by=['thoughts', 'django'])
    
  159.     <QuerySet [<Post: First post>, <Post: Second post>]>
    
  160. 
    
  161.     >>> Post.objects.filter(tags__contained_by=['thoughts', 'django', 'tutorial'])
    
  162.     <QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>
    
  163. 
    
  164. .. fieldlookup:: arrayfield.overlap
    
  165. 
    
  166. ``overlap``
    
  167. ~~~~~~~~~~~
    
  168. 
    
  169. Returns objects where the data shares any results with the values passed. Uses
    
  170. the SQL operator ``&&``. For example::
    
  171. 
    
  172.     >>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
    
  173.     >>> Post.objects.create(name='Second post', tags=['thoughts'])
    
  174.     >>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])
    
  175. 
    
  176.     >>> Post.objects.filter(tags__overlap=['thoughts'])
    
  177.     <QuerySet [<Post: First post>, <Post: Second post>]>
    
  178. 
    
  179.     >>> Post.objects.filter(tags__overlap=['thoughts', 'tutorial'])
    
  180.     <QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>
    
  181. 
    
  182. .. fieldlookup:: arrayfield.len
    
  183. 
    
  184. ``len``
    
  185. ~~~~~~~
    
  186. 
    
  187. Returns the length of the array. The lookups available afterward are those
    
  188. available for :class:`~django.db.models.IntegerField`. For example::
    
  189. 
    
  190.     >>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
    
  191.     >>> Post.objects.create(name='Second post', tags=['thoughts'])
    
  192. 
    
  193.     >>> Post.objects.filter(tags__len=1)
    
  194.     <QuerySet [<Post: Second post>]>
    
  195. 
    
  196. .. fieldlookup:: arrayfield.index
    
  197. 
    
  198. Index transforms
    
  199. ~~~~~~~~~~~~~~~~
    
  200. 
    
  201. Index transforms index into the array. Any non-negative integer can be used.
    
  202. There are no errors if it exceeds the :attr:`size <ArrayField.size>` of the
    
  203. array. The lookups available after the transform are those from the
    
  204. :attr:`base_field <ArrayField.base_field>`. For example::
    
  205. 
    
  206.     >>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
    
  207.     >>> Post.objects.create(name='Second post', tags=['thoughts'])
    
  208. 
    
  209.     >>> Post.objects.filter(tags__0='thoughts')
    
  210.     <QuerySet [<Post: First post>, <Post: Second post>]>
    
  211. 
    
  212.     >>> Post.objects.filter(tags__1__iexact='Django')
    
  213.     <QuerySet [<Post: First post>]>
    
  214. 
    
  215.     >>> Post.objects.filter(tags__276='javascript')
    
  216.     <QuerySet []>
    
  217. 
    
  218. .. note::
    
  219. 
    
  220.     PostgreSQL uses 1-based indexing for array fields when writing raw SQL.
    
  221.     However these indexes and those used in :lookup:`slices <arrayfield.slice>`
    
  222.     use 0-based indexing to be consistent with Python.
    
  223. 
    
  224. .. fieldlookup:: arrayfield.slice
    
  225. 
    
  226. Slice transforms
    
  227. ~~~~~~~~~~~~~~~~
    
  228. 
    
  229. Slice transforms take a slice of the array. Any two non-negative integers can
    
  230. be used, separated by a single underscore. The lookups available after the
    
  231. transform do not change. For example::
    
  232. 
    
  233.     >>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
    
  234.     >>> Post.objects.create(name='Second post', tags=['thoughts'])
    
  235.     >>> Post.objects.create(name='Third post', tags=['django', 'python', 'thoughts'])
    
  236. 
    
  237.     >>> Post.objects.filter(tags__0_1=['thoughts'])
    
  238.     <QuerySet [<Post: First post>, <Post: Second post>]>
    
  239. 
    
  240.     >>> Post.objects.filter(tags__0_2__contains=['thoughts'])
    
  241.     <QuerySet [<Post: First post>, <Post: Second post>]>
    
  242. 
    
  243. .. note::
    
  244. 
    
  245.     PostgreSQL uses 1-based indexing for array fields when writing raw SQL.
    
  246.     However these slices and those used in :lookup:`indexes <arrayfield.index>`
    
  247.     use 0-based indexing to be consistent with Python.
    
  248. 
    
  249. .. admonition:: Multidimensional arrays with indexes and slices
    
  250. 
    
  251.     PostgreSQL has some rather esoteric behavior when using indexes and slices
    
  252.     on multidimensional arrays. It will always work to use indexes to reach
    
  253.     down to the final underlying data, but most other slices behave strangely
    
  254.     at the database level and cannot be supported in a logical, consistent
    
  255.     fashion by Django.
    
  256. 
    
  257. ``CIText`` fields
    
  258. =================
    
  259. 
    
  260. .. class:: CIText(**options)
    
  261. 
    
  262.     A mixin to create case-insensitive text fields backed by the citext_ type.
    
  263.     Read about `the performance considerations`_ prior to using it.
    
  264. 
    
  265.     To use ``citext``, use the :class:`.CITextExtension` operation to
    
  266.     :ref:`set up the citext extension <create-postgresql-extensions>` in
    
  267.     PostgreSQL before the first ``CreateModel`` migration operation.
    
  268. 
    
  269.     If you're using an :class:`~django.contrib.postgres.fields.ArrayField`
    
  270.     of ``CIText`` fields, you must add ``'django.contrib.postgres'`` in your
    
  271.     :setting:`INSTALLED_APPS`, otherwise field values will appear as strings
    
  272.     like ``'{thoughts,django}'``.
    
  273. 
    
  274.     Several fields that use the mixin are provided:
    
  275. 
    
  276. .. class:: CICharField(**options)
    
  277. .. class:: CIEmailField(**options)
    
  278. .. class:: CITextField(**options)
    
  279. 
    
  280.     These fields subclass :class:`~django.db.models.CharField`,
    
  281.     :class:`~django.db.models.EmailField`, and
    
  282.     :class:`~django.db.models.TextField`, respectively.
    
  283. 
    
  284.     ``max_length`` won't be enforced in the database since ``citext`` behaves
    
  285.     similar to PostgreSQL's ``text`` type.
    
  286. 
    
  287.     .. _citext: https://www.postgresql.org/docs/current/citext.html
    
  288.     .. _the performance considerations: https://www.postgresql.org/docs/current/citext.html#id-1.11.7.19.9
    
  289. 
    
  290. .. admonition:: Case-insensitive collations
    
  291. 
    
  292.     On PostgreSQL 12+, it's preferable to use non-deterministic collations
    
  293.     instead of the ``citext`` extension. You can create them using the
    
  294.     :class:`~django.contrib.postgres.operations.CreateCollation` migration
    
  295.     operation. For more details, see :ref:`manage-postgresql-collations` and
    
  296.     the PostgreSQL documentation about `non-deterministic collations`_.
    
  297. 
    
  298.     .. _non-deterministic collations: https://www.postgresql.org/docs/current/collation.html#COLLATION-NONDETERMINISTIC
    
  299. 
    
  300. ``HStoreField``
    
  301. ===============
    
  302. 
    
  303. .. class:: HStoreField(**options)
    
  304. 
    
  305.     A field for storing key-value pairs. The Python data type used is a
    
  306.     ``dict``. Keys must be strings, and values may be either strings or nulls
    
  307.     (``None`` in Python).
    
  308. 
    
  309.     To use this field, you'll need to:
    
  310. 
    
  311.     #. Add ``'django.contrib.postgres'`` in your :setting:`INSTALLED_APPS`.
    
  312.     #. :ref:`Set up the hstore extension <create-postgresql-extensions>` in
    
  313.        PostgreSQL.
    
  314. 
    
  315.     You'll see an error like ``can't adapt type 'dict'`` if you skip the first
    
  316.     step, or ``type "hstore" does not exist`` if you skip the second.
    
  317. 
    
  318. .. note::
    
  319. 
    
  320.     On occasions it may be useful to require or restrict the keys which are
    
  321.     valid for a given field. This can be done using the
    
  322.     :class:`~django.contrib.postgres.validators.KeysValidator`.
    
  323. 
    
  324. Querying ``HStoreField``
    
  325. ------------------------
    
  326. 
    
  327. In addition to the ability to query by key, there are a number of custom
    
  328. lookups available for ``HStoreField``.
    
  329. 
    
  330. We will use the following example model::
    
  331. 
    
  332.     from django.contrib.postgres.fields import HStoreField
    
  333.     from django.db import models
    
  334. 
    
  335.     class Dog(models.Model):
    
  336.         name = models.CharField(max_length=200)
    
  337.         data = HStoreField()
    
  338. 
    
  339.         def __str__(self):
    
  340.             return self.name
    
  341. 
    
  342. .. fieldlookup:: hstorefield.key
    
  343. 
    
  344. Key lookups
    
  345. ~~~~~~~~~~~
    
  346. 
    
  347. To query based on a given key, you can use that key as the lookup name::
    
  348. 
    
  349.     >>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
    
  350.     >>> Dog.objects.create(name='Meg', data={'breed': 'collie'})
    
  351. 
    
  352.     >>> Dog.objects.filter(data__breed='collie')
    
  353.     <QuerySet [<Dog: Meg>]>
    
  354. 
    
  355. You can chain other lookups after key lookups::
    
  356. 
    
  357.     >>> Dog.objects.filter(data__breed__contains='l')
    
  358.     <QuerySet [<Dog: Rufus>, <Dog: Meg>]>
    
  359. 
    
  360. or use ``F()`` expressions to annotate a key value. For example::
    
  361. 
    
  362.     >>> from django.db.models import F
    
  363.     >>> rufus = Dog.objects.annotate(breed=F("data__breed"))[0]
    
  364.     >>> rufus.breed
    
  365.     'labrador'
    
  366. 
    
  367. If the key you wish to query by clashes with the name of another lookup, you
    
  368. need to use the :lookup:`hstorefield.contains` lookup instead.
    
  369. 
    
  370. .. note::
    
  371. 
    
  372.     Key transforms can also be chained with: :lookup:`contains`,
    
  373.     :lookup:`icontains`, :lookup:`endswith`, :lookup:`iendswith`,
    
  374.     :lookup:`iexact`, :lookup:`regex`, :lookup:`iregex`, :lookup:`startswith`,
    
  375.     and :lookup:`istartswith` lookups.
    
  376. 
    
  377. .. warning::
    
  378. 
    
  379.     Since any string could be a key in a hstore value, any lookup other than
    
  380.     those listed below will be interpreted as a key lookup. No errors are
    
  381.     raised. Be extra careful for typing mistakes, and always check your queries
    
  382.     work as you intend.
    
  383. 
    
  384. .. fieldlookup:: hstorefield.contains
    
  385. 
    
  386. ``contains``
    
  387. ~~~~~~~~~~~~
    
  388. 
    
  389. The :lookup:`contains` lookup is overridden on
    
  390. :class:`~django.contrib.postgres.fields.HStoreField`. The returned objects are
    
  391. those where the given ``dict`` of key-value pairs are all contained in the
    
  392. field. It uses the SQL operator ``@>``. For example::
    
  393. 
    
  394.     >>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'})
    
  395.     >>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
    
  396.     >>> Dog.objects.create(name='Fred', data={})
    
  397. 
    
  398.     >>> Dog.objects.filter(data__contains={'owner': 'Bob'})
    
  399.     <QuerySet [<Dog: Rufus>, <Dog: Meg>]>
    
  400. 
    
  401.     >>> Dog.objects.filter(data__contains={'breed': 'collie'})
    
  402.     <QuerySet [<Dog: Meg>]>
    
  403. 
    
  404. .. fieldlookup:: hstorefield.contained_by
    
  405. 
    
  406. ``contained_by``
    
  407. ~~~~~~~~~~~~~~~~
    
  408. 
    
  409. This is the inverse of the :lookup:`contains <hstorefield.contains>` lookup -
    
  410. the objects returned will be those where the key-value pairs on the object are
    
  411. a subset of those in the value passed. It uses the SQL operator ``<@``. For
    
  412. example::
    
  413. 
    
  414.     >>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'})
    
  415.     >>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
    
  416.     >>> Dog.objects.create(name='Fred', data={})
    
  417. 
    
  418.     >>> Dog.objects.filter(data__contained_by={'breed': 'collie', 'owner': 'Bob'})
    
  419.     <QuerySet [<Dog: Meg>, <Dog: Fred>]>
    
  420. 
    
  421.     >>> Dog.objects.filter(data__contained_by={'breed': 'collie'})
    
  422.     <QuerySet [<Dog: Fred>]>
    
  423. 
    
  424. .. fieldlookup:: hstorefield.has_key
    
  425. 
    
  426. ``has_key``
    
  427. ~~~~~~~~~~~
    
  428. 
    
  429. Returns objects where the given key is in the data. Uses the SQL operator
    
  430. ``?``. For example::
    
  431. 
    
  432.     >>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
    
  433.     >>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
    
  434. 
    
  435.     >>> Dog.objects.filter(data__has_key='owner')
    
  436.     <QuerySet [<Dog: Meg>]>
    
  437. 
    
  438. .. fieldlookup:: hstorefield.has_any_keys
    
  439. 
    
  440. ``has_any_keys``
    
  441. ~~~~~~~~~~~~~~~~
    
  442. 
    
  443. Returns objects where any of the given keys are in the data. Uses the SQL
    
  444. operator ``?|``. For example::
    
  445. 
    
  446.     >>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
    
  447.     >>> Dog.objects.create(name='Meg', data={'owner': 'Bob'})
    
  448.     >>> Dog.objects.create(name='Fred', data={})
    
  449. 
    
  450.     >>> Dog.objects.filter(data__has_any_keys=['owner', 'breed'])
    
  451.     <QuerySet [<Dog: Rufus>, <Dog: Meg>]>
    
  452. 
    
  453. .. fieldlookup:: hstorefield.has_keys
    
  454. 
    
  455. ``has_keys``
    
  456. ~~~~~~~~~~~~
    
  457. 
    
  458. Returns objects where all of the given keys are in the data. Uses the SQL operator
    
  459. ``?&``. For example::
    
  460. 
    
  461.     >>> Dog.objects.create(name='Rufus', data={})
    
  462.     >>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
    
  463. 
    
  464.     >>> Dog.objects.filter(data__has_keys=['breed', 'owner'])
    
  465.     <QuerySet [<Dog: Meg>]>
    
  466. 
    
  467. .. fieldlookup:: hstorefield.keys
    
  468. 
    
  469. ``keys``
    
  470. ~~~~~~~~
    
  471. 
    
  472. Returns objects where the array of keys is the given value. Note that the order
    
  473. is not guaranteed to be reliable, so this transform is mainly useful for using
    
  474. in conjunction with lookups on
    
  475. :class:`~django.contrib.postgres.fields.ArrayField`. Uses the SQL function
    
  476. ``akeys()``. For example::
    
  477. 
    
  478.     >>> Dog.objects.create(name='Rufus', data={'toy': 'bone'})
    
  479.     >>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
    
  480. 
    
  481.     >>> Dog.objects.filter(data__keys__overlap=['breed', 'toy'])
    
  482.     <QuerySet [<Dog: Rufus>, <Dog: Meg>]>
    
  483. 
    
  484. .. fieldlookup:: hstorefield.values
    
  485. 
    
  486. ``values``
    
  487. ~~~~~~~~~~
    
  488. 
    
  489. Returns objects where the array of values is the given value. Note that the
    
  490. order is not guaranteed to be reliable, so this transform is mainly useful for
    
  491. using in conjunction with lookups on
    
  492. :class:`~django.contrib.postgres.fields.ArrayField`. Uses the SQL function
    
  493. ``avals()``. For example::
    
  494. 
    
  495.     >>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
    
  496.     >>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
    
  497. 
    
  498.     >>> Dog.objects.filter(data__values__contains=['collie'])
    
  499.     <QuerySet [<Dog: Meg>]>
    
  500. 
    
  501. .. _range-fields:
    
  502. 
    
  503. Range Fields
    
  504. ============
    
  505. 
    
  506. There are five range field types, corresponding to the built-in range types in
    
  507. PostgreSQL. These fields are used to store a range of values; for example the
    
  508. start and end timestamps of an event, or the range of ages an activity is
    
  509. suitable for.
    
  510. 
    
  511. All of the range fields translate to :ref:`psycopg2 Range objects
    
  512. <psycopg2:adapt-range>` in Python, but also accept tuples as input if no bounds
    
  513. information is necessary. The default is lower bound included, upper bound
    
  514. excluded, that is ``[)`` (see the PostgreSQL documentation for details about
    
  515. `different bounds`_). The default bounds can be changed for non-discrete range
    
  516. fields (:class:`.DateTimeRangeField` and :class:`.DecimalRangeField`) by using
    
  517. the ``default_bounds`` argument.
    
  518. 
    
  519. ``IntegerRangeField``
    
  520. ---------------------
    
  521. 
    
  522. .. class:: IntegerRangeField(**options)
    
  523. 
    
  524.     Stores a range of integers. Based on an
    
  525.     :class:`~django.db.models.IntegerField`. Represented by an ``int4range`` in
    
  526.     the database and a :class:`~psycopg2:psycopg2.extras.NumericRange` in
    
  527.     Python.
    
  528. 
    
  529.     Regardless of the bounds specified when saving the data, PostgreSQL always
    
  530.     returns a range in a canonical form that includes the lower bound and
    
  531.     excludes the upper bound, that is ``[)``.
    
  532. 
    
  533. ``BigIntegerRangeField``
    
  534. ------------------------
    
  535. 
    
  536. .. class:: BigIntegerRangeField(**options)
    
  537. 
    
  538.     Stores a range of large integers. Based on a
    
  539.     :class:`~django.db.models.BigIntegerField`. Represented by an ``int8range``
    
  540.     in the database and a :class:`~psycopg2:psycopg2.extras.NumericRange` in
    
  541.     Python.
    
  542. 
    
  543.     Regardless of the bounds specified when saving the data, PostgreSQL always
    
  544.     returns a range in a canonical form that includes the lower bound and
    
  545.     excludes the upper bound, that is ``[)``.
    
  546. 
    
  547. ``DecimalRangeField``
    
  548. ---------------------
    
  549. 
    
  550. .. class:: DecimalRangeField(default_bounds='[)', **options)
    
  551. 
    
  552.     Stores a range of floating point values. Based on a
    
  553.     :class:`~django.db.models.DecimalField`. Represented by a ``numrange`` in
    
  554.     the database and a :class:`~psycopg2:psycopg2.extras.NumericRange` in
    
  555.     Python.
    
  556. 
    
  557.     .. attribute:: DecimalRangeField.default_bounds
    
  558. 
    
  559.         .. versionadded:: 4.1
    
  560. 
    
  561.         Optional. The value of ``bounds`` for list and tuple inputs. The
    
  562.         default is lower bound included, upper bound excluded, that is ``[)``
    
  563.         (see the PostgreSQL documentation for details about
    
  564.         `different bounds`_). ``default_bounds`` is not used for
    
  565.         :class:`~psycopg2:psycopg2.extras.NumericRange` inputs.
    
  566. 
    
  567. ``DateTimeRangeField``
    
  568. ----------------------
    
  569. 
    
  570. .. class:: DateTimeRangeField(default_bounds='[)', **options)
    
  571. 
    
  572.     Stores a range of timestamps. Based on a
    
  573.     :class:`~django.db.models.DateTimeField`. Represented by a ``tstzrange`` in
    
  574.     the database and a :class:`~psycopg2:psycopg2.extras.DateTimeTZRange` in
    
  575.     Python.
    
  576. 
    
  577.     .. attribute:: DateTimeRangeField.default_bounds
    
  578. 
    
  579.         .. versionadded:: 4.1
    
  580. 
    
  581.         Optional. The value of ``bounds`` for list and tuple inputs. The
    
  582.         default is lower bound included, upper bound excluded, that is ``[)``
    
  583.         (see the PostgreSQL documentation for details about
    
  584.         `different bounds`_). ``default_bounds`` is not used for
    
  585.         :class:`~psycopg2:psycopg2.extras.DateTimeTZRange` inputs.
    
  586. 
    
  587. ``DateRangeField``
    
  588. ------------------
    
  589. 
    
  590. .. class:: DateRangeField(**options)
    
  591. 
    
  592.     Stores a range of dates. Based on a
    
  593.     :class:`~django.db.models.DateField`. Represented by a ``daterange`` in the
    
  594.     database and a :class:`~psycopg2:psycopg2.extras.DateRange` in Python.
    
  595. 
    
  596.     Regardless of the bounds specified when saving the data, PostgreSQL always
    
  597.     returns a range in a canonical form that includes the lower bound and
    
  598.     excludes the upper bound, that is ``[)``.
    
  599. 
    
  600. Querying Range Fields
    
  601. ---------------------
    
  602. 
    
  603. There are a number of custom lookups and transforms for range fields. They are
    
  604. available on all the above fields, but we will use the following example
    
  605. model::
    
  606. 
    
  607.     from django.contrib.postgres.fields import IntegerRangeField
    
  608.     from django.db import models
    
  609. 
    
  610.     class Event(models.Model):
    
  611.         name = models.CharField(max_length=200)
    
  612.         ages = IntegerRangeField()
    
  613.         start = models.DateTimeField()
    
  614. 
    
  615.         def __str__(self):
    
  616.             return self.name
    
  617. 
    
  618. We will also use the following example objects::
    
  619. 
    
  620.     >>> import datetime
    
  621.     >>> from django.utils import timezone
    
  622.     >>> now = timezone.now()
    
  623.     >>> Event.objects.create(name='Soft play', ages=(0, 10), start=now)
    
  624.     >>> Event.objects.create(name='Pub trip', ages=(21, None), start=now - datetime.timedelta(days=1))
    
  625. 
    
  626. and ``NumericRange``:
    
  627. 
    
  628.     >>> from psycopg2.extras import NumericRange
    
  629. 
    
  630. Containment functions
    
  631. ~~~~~~~~~~~~~~~~~~~~~
    
  632. 
    
  633. As with other PostgreSQL fields, there are three standard containment
    
  634. operators: ``contains``, ``contained_by`` and ``overlap``, using the SQL
    
  635. operators ``@>``, ``<@``, and ``&&`` respectively.
    
  636. 
    
  637. .. fieldlookup:: rangefield.contains
    
  638. 
    
  639. ``contains``
    
  640. ^^^^^^^^^^^^
    
  641. 
    
  642.     >>> Event.objects.filter(ages__contains=NumericRange(4, 5))
    
  643.     <QuerySet [<Event: Soft play>]>
    
  644. 
    
  645. .. fieldlookup:: rangefield.contained_by
    
  646. 
    
  647. ``contained_by``
    
  648. ^^^^^^^^^^^^^^^^
    
  649. 
    
  650.     >>> Event.objects.filter(ages__contained_by=NumericRange(0, 15))
    
  651.     <QuerySet [<Event: Soft play>]>
    
  652. 
    
  653. The ``contained_by`` lookup is also available on the non-range field types:
    
  654. :class:`~django.db.models.SmallAutoField`,
    
  655. :class:`~django.db.models.AutoField`, :class:`~django.db.models.BigAutoField`,
    
  656. :class:`~django.db.models.SmallIntegerField`,
    
  657. :class:`~django.db.models.IntegerField`,
    
  658. :class:`~django.db.models.BigIntegerField`,
    
  659. :class:`~django.db.models.DecimalField`, :class:`~django.db.models.FloatField`,
    
  660. :class:`~django.db.models.DateField`, and
    
  661. :class:`~django.db.models.DateTimeField`. For example::
    
  662. 
    
  663.     >>> from psycopg2.extras import DateTimeTZRange
    
  664.     >>> Event.objects.filter(
    
  665.     ...     start__contained_by=DateTimeTZRange(
    
  666.     ...         timezone.now() - datetime.timedelta(hours=1),
    
  667.     ...         timezone.now() + datetime.timedelta(hours=1),
    
  668.     ...     ),
    
  669.     ... )
    
  670.     <QuerySet [<Event: Soft play>]>
    
  671. 
    
  672. .. fieldlookup:: rangefield.overlap
    
  673. 
    
  674. ``overlap``
    
  675. ^^^^^^^^^^^
    
  676. 
    
  677.     >>> Event.objects.filter(ages__overlap=NumericRange(8, 12))
    
  678.     <QuerySet [<Event: Soft play>]>
    
  679. 
    
  680. Comparison functions
    
  681. ~~~~~~~~~~~~~~~~~~~~
    
  682. 
    
  683. Range fields support the standard lookups: :lookup:`lt`, :lookup:`gt`,
    
  684. :lookup:`lte` and :lookup:`gte`. These are not particularly helpful - they
    
  685. compare the lower bounds first and then the upper bounds only if necessary.
    
  686. This is also the strategy used to order by a range field. It is better to use
    
  687. the specific range comparison operators.
    
  688. 
    
  689. .. fieldlookup:: rangefield.fully_lt
    
  690. 
    
  691. ``fully_lt``
    
  692. ^^^^^^^^^^^^
    
  693. 
    
  694. The returned ranges are strictly less than the passed range. In other words,
    
  695. all the points in the returned range are less than all those in the passed
    
  696. range.
    
  697. 
    
  698.     >>> Event.objects.filter(ages__fully_lt=NumericRange(11, 15))
    
  699.     <QuerySet [<Event: Soft play>]>
    
  700. 
    
  701. .. fieldlookup:: rangefield.fully_gt
    
  702. 
    
  703. ``fully_gt``
    
  704. ^^^^^^^^^^^^
    
  705. 
    
  706. The returned ranges are strictly greater than the passed range. In other words,
    
  707. the all the points in the returned range are greater than all those in the
    
  708. passed range.
    
  709. 
    
  710.     >>> Event.objects.filter(ages__fully_gt=NumericRange(11, 15))
    
  711.     <QuerySet [<Event: Pub trip>]>
    
  712. 
    
  713. .. fieldlookup:: rangefield.not_lt
    
  714. 
    
  715. ``not_lt``
    
  716. ^^^^^^^^^^
    
  717. 
    
  718. The returned ranges do not contain any points less than the passed range, that
    
  719. is the lower bound of the returned range is at least the lower bound of the
    
  720. passed range.
    
  721. 
    
  722.     >>> Event.objects.filter(ages__not_lt=NumericRange(0, 15))
    
  723.     <QuerySet [<Event: Soft play>, <Event: Pub trip>]>
    
  724. 
    
  725. .. fieldlookup:: rangefield.not_gt
    
  726. 
    
  727. ``not_gt``
    
  728. ^^^^^^^^^^
    
  729. 
    
  730. The returned ranges do not contain any points greater than the passed range, that
    
  731. is the upper bound of the returned range is at most the upper bound of the
    
  732. passed range.
    
  733. 
    
  734.     >>> Event.objects.filter(ages__not_gt=NumericRange(3, 10))
    
  735.     <QuerySet [<Event: Soft play>]>
    
  736. 
    
  737. .. fieldlookup:: rangefield.adjacent_to
    
  738. 
    
  739. ``adjacent_to``
    
  740. ^^^^^^^^^^^^^^^
    
  741. 
    
  742. The returned ranges share a bound with the passed range.
    
  743. 
    
  744.     >>> Event.objects.filter(ages__adjacent_to=NumericRange(10, 21))
    
  745.     <QuerySet [<Event: Soft play>, <Event: Pub trip>]>
    
  746. 
    
  747. Querying using the bounds
    
  748. ~~~~~~~~~~~~~~~~~~~~~~~~~
    
  749. 
    
  750. Range fields support several extra lookups.
    
  751. 
    
  752. .. fieldlookup:: rangefield.startswith
    
  753. 
    
  754. ``startswith``
    
  755. ^^^^^^^^^^^^^^
    
  756. 
    
  757. Returned objects have the given lower bound. Can be chained to valid lookups
    
  758. for the base field.
    
  759. 
    
  760.     >>> Event.objects.filter(ages__startswith=21)
    
  761.     <QuerySet [<Event: Pub trip>]>
    
  762. 
    
  763. .. fieldlookup:: rangefield.endswith
    
  764. 
    
  765. ``endswith``
    
  766. ^^^^^^^^^^^^
    
  767. 
    
  768. Returned objects have the given upper bound. Can be chained to valid lookups
    
  769. for the base field.
    
  770. 
    
  771.     >>> Event.objects.filter(ages__endswith=10)
    
  772.     <QuerySet [<Event: Soft play>]>
    
  773. 
    
  774. .. fieldlookup:: rangefield.isempty
    
  775. 
    
  776. ``isempty``
    
  777. ^^^^^^^^^^^
    
  778. 
    
  779. Returned objects are empty ranges. Can be chained to valid lookups for a
    
  780. :class:`~django.db.models.BooleanField`.
    
  781. 
    
  782.     >>> Event.objects.filter(ages__isempty=True)
    
  783.     <QuerySet []>
    
  784. 
    
  785. .. fieldlookup:: rangefield.lower_inc
    
  786. 
    
  787. ``lower_inc``
    
  788. ^^^^^^^^^^^^^
    
  789. 
    
  790. Returns objects that have inclusive or exclusive lower bounds, depending on the
    
  791. boolean value passed. Can be chained to valid lookups for a
    
  792. :class:`~django.db.models.BooleanField`.
    
  793. 
    
  794.     >>> Event.objects.filter(ages__lower_inc=True)
    
  795.     <QuerySet [<Event: Soft play>, <Event: Pub trip>]>
    
  796. 
    
  797. .. fieldlookup:: rangefield.lower_inf
    
  798. 
    
  799. ``lower_inf``
    
  800. ^^^^^^^^^^^^^
    
  801. 
    
  802. Returns objects that have unbounded (infinite) or bounded lower bound,
    
  803. depending on the boolean value passed. Can be chained to valid lookups for a
    
  804. :class:`~django.db.models.BooleanField`.
    
  805. 
    
  806.     >>> Event.objects.filter(ages__lower_inf=True)
    
  807.     <QuerySet []>
    
  808. 
    
  809. .. fieldlookup:: rangefield.upper_inc
    
  810. 
    
  811. ``upper_inc``
    
  812. ^^^^^^^^^^^^^
    
  813. 
    
  814. Returns objects that have inclusive or exclusive upper bounds, depending on the
    
  815. boolean value passed. Can be chained to valid lookups for a
    
  816. :class:`~django.db.models.BooleanField`.
    
  817. 
    
  818.     >>> Event.objects.filter(ages__upper_inc=True)
    
  819.     <QuerySet []>
    
  820. 
    
  821. .. fieldlookup:: rangefield.upper_inf
    
  822. 
    
  823. ``upper_inf``
    
  824. ^^^^^^^^^^^^^
    
  825. 
    
  826. Returns objects that have unbounded (infinite) or bounded upper bound,
    
  827. depending on the boolean value passed. Can be chained to valid lookups for a
    
  828. :class:`~django.db.models.BooleanField`.
    
  829. 
    
  830.     >>> Event.objects.filter(ages__upper_inf=True)
    
  831.     <QuerySet [<Event: Pub trip>]>
    
  832. 
    
  833. Defining your own range types
    
  834. -----------------------------
    
  835. 
    
  836. PostgreSQL allows the definition of custom range types. Django's model and form
    
  837. field implementations use base classes below, and psycopg2 provides a
    
  838. :func:`~psycopg2:psycopg2.extras.register_range` to allow use of custom range
    
  839. types.
    
  840. 
    
  841. .. class:: RangeField(**options)
    
  842. 
    
  843.     Base class for model range fields.
    
  844. 
    
  845.     .. attribute:: base_field
    
  846. 
    
  847.         The model field class to use.
    
  848. 
    
  849.     .. attribute:: range_type
    
  850. 
    
  851.         The psycopg2 range type to use.
    
  852. 
    
  853.     .. attribute:: form_field
    
  854. 
    
  855.         The form field class to use. Should be a subclass of
    
  856.         :class:`django.contrib.postgres.forms.BaseRangeField`.
    
  857. 
    
  858. .. class:: django.contrib.postgres.forms.BaseRangeField
    
  859. 
    
  860.     Base class for form range fields.
    
  861. 
    
  862.     .. attribute:: base_field
    
  863. 
    
  864.         The form field to use.
    
  865. 
    
  866.     .. attribute:: range_type
    
  867. 
    
  868.         The psycopg2 range type to use.
    
  869. 
    
  870. Range operators
    
  871. ---------------
    
  872. 
    
  873. .. class:: RangeOperators
    
  874. 
    
  875. PostgreSQL provides a set of SQL operators that can be used together with the
    
  876. range data types (see `the PostgreSQL documentation for the full details of
    
  877. range operators <https://www.postgresql.org/docs/current/
    
  878. functions-range.html#RANGE-OPERATORS-TABLE>`_). This class is meant as a
    
  879. convenient method to avoid typos. The operator names overlap with the names of
    
  880. corresponding lookups.
    
  881. 
    
  882. .. code-block:: python
    
  883. 
    
  884.     class RangeOperators:
    
  885.         EQUAL = '='
    
  886.         NOT_EQUAL = '<>'
    
  887.         CONTAINS = '@>'
    
  888.         CONTAINED_BY = '<@'
    
  889.         OVERLAPS = '&&'
    
  890.         FULLY_LT = '<<'
    
  891.         FULLY_GT = '>>'
    
  892.         NOT_LT = '&>'
    
  893.         NOT_GT = '&<'
    
  894.         ADJACENT_TO = '-|-'
    
  895. 
    
  896. RangeBoundary() expressions
    
  897. ---------------------------
    
  898. 
    
  899. .. class:: RangeBoundary(inclusive_lower=True, inclusive_upper=False)
    
  900. 
    
  901.     .. attribute:: inclusive_lower
    
  902. 
    
  903.         If ``True`` (default), the lower bound is inclusive ``'['``, otherwise
    
  904.         it's exclusive ``'('``.
    
  905. 
    
  906.     .. attribute:: inclusive_upper
    
  907. 
    
  908.         If ``False`` (default), the upper bound is exclusive ``')'``, otherwise
    
  909.         it's inclusive ``']'``.
    
  910. 
    
  911. A ``RangeBoundary()`` expression represents the range boundaries. It can be
    
  912. used with a custom range functions that expected boundaries, for example to
    
  913. define :class:`~django.contrib.postgres.constraints.ExclusionConstraint`. See
    
  914. `the PostgreSQL documentation for the full details <https://www.postgresql.org/
    
  915. docs/current/rangetypes.html#RANGETYPES-INCLUSIVITY>`_.
    
  916. 
    
  917. .. _different bounds: https://www.postgresql.org/docs/current/rangetypes.html#RANGETYPES-IO