Fixed #34140 -- Reformatted code blocks in docs with blacken-docs.

This commit is contained in:
django-bot 2023-02-28 20:53:28 +01:00 committed by Mariusz Felisiak
parent 6015bab80e
commit 14459f80ee
193 changed files with 5797 additions and 4481 deletions

View file

@ -16,7 +16,7 @@ module. They are described in more detail in the `PostgreSQL docs
.. code-block:: pycon
>>> SomeModel.objects.aggregate(arr=ArrayAgg('somefield'))
>>> SomeModel.objects.aggregate(arr=ArrayAgg("somefield"))
{'arr': [0, 1, 2]}
.. admonition:: Common aggregate options
@ -49,10 +49,11 @@ General-purpose aggregation functions
Examples::
'some_field'
'-some_field'
"some_field"
"-some_field"
from django.db.models import F
F('some_field').desc()
F("some_field").desc()
.. versionchanged:: 5.0
@ -103,7 +104,7 @@ General-purpose aggregation functions
>>> from django.db.models import Q
>>> from django.contrib.postgres.aggregates import BoolAnd
>>> Comment.objects.aggregate(booland=BoolAnd('published'))
>>> Comment.objects.aggregate(booland=BoolAnd("published"))
{'booland': False}
>>> Comment.objects.aggregate(booland=BoolAnd(Q(rank__lt=100)))
{'booland': True}
@ -127,7 +128,7 @@ General-purpose aggregation functions
>>> from django.db.models import Q
>>> from django.contrib.postgres.aggregates import BoolOr
>>> Comment.objects.aggregate(boolor=BoolOr('published'))
>>> Comment.objects.aggregate(boolor=BoolOr("published"))
{'boolor': True}
>>> Comment.objects.aggregate(boolor=BoolOr(Q(rank__gt=2)))
{'boolor': False}
@ -160,8 +161,9 @@ General-purpose aggregation functions
class Room(models.Model):
number = models.IntegerField(unique=True)
class HotelReservation(models.Model):
room = models.ForeignKey('Room', on_delete=models.CASCADE)
room = models.ForeignKey("Room", on_delete=models.CASCADE)
start = models.DateTimeField()
end = models.DateTimeField()
requirements = models.JSONField(blank=True, null=True)
@ -171,10 +173,10 @@ General-purpose aggregation functions
>>> from django.contrib.postgres.aggregates import JSONBAgg
>>> Room.objects.annotate(
... requirements=JSONBAgg(
... 'hotelreservation__requirements',
... ordering='-hotelreservation__start',
... "hotelreservation__requirements",
... ordering="-hotelreservation__start",
... )
... ).filter(requirements__0__sea_view=True).values('number', 'requirements')
... ).filter(requirements__0__sea_view=True).values("number", "requirements")
<QuerySet [{'number': 102, 'requirements': [
{'parking': False, 'sea_view': True, 'double_bed': False},
{'parking': True, 'double_bed': True}
@ -217,6 +219,7 @@ General-purpose aggregation functions
class Publication(models.Model):
title = models.CharField(max_length=30)
class Article(models.Model):
headline = models.CharField(max_length=100)
publications = models.ManyToManyField(Publication)
@ -373,11 +376,11 @@ Here's some examples of some of the general-purpose aggregation functions:
.. code-block:: pycon
>>> TestModel.objects.aggregate(result=StringAgg('field1', delimiter=';'))
>>> TestModel.objects.aggregate(result=StringAgg("field1", delimiter=";"))
{'result': 'foo;bar;test'}
>>> TestModel.objects.aggregate(result=ArrayAgg('field2'))
>>> TestModel.objects.aggregate(result=ArrayAgg("field2"))
{'result': [1, 2, 3]}
>>> TestModel.objects.aggregate(result=ArrayAgg('field1'))
>>> TestModel.objects.aggregate(result=ArrayAgg("field1"))
{'result': ['foo', 'bar', 'test']}
The next example shows the usage of statistical aggregate functions. The
@ -386,8 +389,9 @@ underlying math will be not described (you can read about this, for example, at
.. code-block:: pycon
>>> TestModel.objects.aggregate(count=RegrCount(y='field3', x='field2'))
>>> TestModel.objects.aggregate(count=RegrCount(y="field3", x="field2"))
{'count': 2}
>>> TestModel.objects.aggregate(avgx=RegrAvgX(y='field3', x='field2'),
... avgy=RegrAvgY(y='field3', x='field2'))
>>> TestModel.objects.aggregate(
... avgx=RegrAvgX(y="field3", x="field2"), avgy=RegrAvgY(y="field3", x="field2")
... )
{'avgx': 2, 'avgy': 13}

View file

@ -47,9 +47,9 @@ second element is an SQL operator represented as a string. To avoid typos, you
may use :class:`~django.contrib.postgres.fields.RangeOperators` which maps the
operators with strings. For example::
expressions=[
('timespan', RangeOperators.ADJACENT_TO),
(F('room'), RangeOperators.EQUAL),
expressions = [
("timespan", RangeOperators.ADJACENT_TO),
(F("room"), RangeOperators.EQUAL),
]
.. admonition:: Restrictions on operators.
@ -60,8 +60,8 @@ The :class:`OpClass() <django.contrib.postgres.indexes.OpClass>` expression can
be used to specify a custom `operator class`_ for the constraint expressions.
For example::
expressions=[
(OpClass('circle', name='circle_ops'), RangeOperators.OVERLAPS),
expressions = [
(OpClass("circle", name="circle_ops"), RangeOperators.OVERLAPS),
]
creates an exclusion constraint on ``circle`` using ``circle_ops``.
@ -103,9 +103,9 @@ are ``Deferrable.DEFERRED`` or ``Deferrable.IMMEDIATE``. For example::
ExclusionConstraint(
name='exclude_overlapping_deferred',
name="exclude_overlapping_deferred",
expressions=[
('timespan', RangeOperators.OVERLAPS),
("timespan", RangeOperators.OVERLAPS),
],
deferrable=Deferrable.DEFERRED,
)
@ -161,22 +161,23 @@ taking canceled reservations into account::
from django.db import models
from django.db.models import Q
class Room(models.Model):
number = models.IntegerField()
class Reservation(models.Model):
room = models.ForeignKey('Room', on_delete=models.CASCADE)
room = models.ForeignKey("Room", on_delete=models.CASCADE)
timespan = DateTimeRangeField()
cancelled = models.BooleanField(default=False)
class Meta:
constraints = [
ExclusionConstraint(
name='exclude_overlapping_reservations',
name="exclude_overlapping_reservations",
expressions=[
('timespan', RangeOperators.OVERLAPS),
('room', RangeOperators.EQUAL),
("timespan", RangeOperators.OVERLAPS),
("room", RangeOperators.EQUAL),
],
condition=Q(cancelled=False),
),
@ -202,12 +203,12 @@ current/rangetypes.html#RANGETYPES-INCLUSIVITY>`_. For example::
class TsTzRange(Func):
function = 'TSTZRANGE'
function = "TSTZRANGE"
output_field = DateTimeRangeField()
class Reservation(models.Model):
room = models.ForeignKey('Room', on_delete=models.CASCADE)
room = models.ForeignKey("Room", on_delete=models.CASCADE)
start = models.DateTimeField()
end = models.DateTimeField()
cancelled = models.BooleanField(default=False)
@ -215,10 +216,13 @@ current/rangetypes.html#RANGETYPES-INCLUSIVITY>`_. For example::
class Meta:
constraints = [
ExclusionConstraint(
name='exclude_overlapping_reservations',
name="exclude_overlapping_reservations",
expressions=[
(TsTzRange('start', 'end', RangeBoundary()), RangeOperators.OVERLAPS),
('room', RangeOperators.EQUAL),
(
TsTzRange("start", "end", RangeBoundary()),
RangeOperators.OVERLAPS,
),
("room", RangeOperators.EQUAL),
],
condition=Q(cancelled=False),
),

View file

@ -29,8 +29,8 @@ objects:
>>> from django.db.models import OuterRef
>>> from django.db.models.functions import JSONObject
>>> from django.contrib.postgres.expressions import ArraySubquery
>>> books = Book.objects.filter(author=OuterRef('pk')).values(
... json=JSONObject(title='title', pages='pages')
>>> books = Book.objects.filter(author=OuterRef("pk")).values(
... json=JSONObject(title="title", pages="pages")
... )
>>> author = Author.objects.annotate(books=ArraySubquery(books)).first()
>>> author.books

View file

@ -57,6 +57,7 @@ may be a good choice for the :ref:`range fields <range-fields>` and
from django.contrib.postgres.fields import ArrayField
from django.db import models
class ChessBoard(models.Model):
board = ArrayField(
ArrayField(
@ -86,20 +87,26 @@ may be a good choice for the :ref:`range fields <range-fields>` and
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],
])
Board(
pieces=[
[2, 3],
[2, 1],
]
)
# Not valid
Board(pieces=[
[2, 3],
[2],
])
Board(
pieces=[
[2, 3],
[2],
]
)
If irregular shapes are required, then the underlying field should be made
nullable and the values padded with ``None``.
@ -113,6 +120,7 @@ We will use the following example model::
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)
@ -131,17 +139,17 @@ data. It uses the SQL operator ``@>``. For example:
.. code-block:: pycon
>>> 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.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'])
>>> Post.objects.filter(tags__contains=["thoughts"])
<QuerySet [<Post: First post>, <Post: Second post>]>
>>> Post.objects.filter(tags__contains=['django'])
>>> Post.objects.filter(tags__contains=["django"])
<QuerySet [<Post: First post>, <Post: Third post>]>
>>> Post.objects.filter(tags__contains=['django', 'thoughts'])
>>> Post.objects.filter(tags__contains=["django", "thoughts"])
<QuerySet [<Post: First post>]>
.. fieldlookup:: arrayfield.contained_by
@ -155,14 +163,14 @@ passed. It uses the SQL operator ``<@``. For example:
.. code-block:: pycon
>>> 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.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'])
>>> Post.objects.filter(tags__contained_by=["thoughts", "django"])
<QuerySet [<Post: First post>, <Post: Second post>]>
>>> Post.objects.filter(tags__contained_by=['thoughts', 'django', 'tutorial'])
>>> Post.objects.filter(tags__contained_by=["thoughts", "django", "tutorial"])
<QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>
.. fieldlookup:: arrayfield.overlap
@ -175,17 +183,17 @@ the SQL operator ``&&``. For example:
.. code-block:: pycon
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts', 'tutorial'])
>>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])
>>> Post.objects.create(name="First post", tags=["thoughts", "django"])
>>> Post.objects.create(name="Second post", tags=["thoughts", "tutorial"])
>>> Post.objects.create(name="Third post", tags=["tutorial", "django"])
>>> Post.objects.filter(tags__overlap=['thoughts'])
>>> Post.objects.filter(tags__overlap=["thoughts"])
<QuerySet [<Post: First post>, <Post: Second post>]>
>>> Post.objects.filter(tags__overlap=['thoughts', 'tutorial'])
>>> Post.objects.filter(tags__overlap=["thoughts", "tutorial"])
<QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>
>>> Post.objects.filter(tags__overlap=Post.objects.values_list('tags'))
>>> Post.objects.filter(tags__overlap=Post.objects.values_list("tags"))
<QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>
.. versionchanged:: 4.2
@ -203,8 +211,8 @@ available for :class:`~django.db.models.IntegerField`. For example:
.. code-block:: pycon
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
>>> 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>]>
@ -221,16 +229,16 @@ array. The lookups available after the transform are those from the
.. code-block:: pycon
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
>>> Post.objects.create(name="First post", tags=["thoughts", "django"])
>>> Post.objects.create(name="Second post", tags=["thoughts"])
>>> Post.objects.filter(tags__0='thoughts')
>>> Post.objects.filter(tags__0="thoughts")
<QuerySet [<Post: First post>, <Post: Second post>]>
>>> Post.objects.filter(tags__1__iexact='Django')
>>> Post.objects.filter(tags__1__iexact="Django")
<QuerySet [<Post: First post>]>
>>> Post.objects.filter(tags__276='javascript')
>>> Post.objects.filter(tags__276="javascript")
<QuerySet []>
.. note::
@ -250,14 +258,14 @@ transform do not change. For example:
.. code-block:: pycon
>>> 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.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'])
>>> Post.objects.filter(tags__0_1=["thoughts"])
<QuerySet [<Post: First post>, <Post: Second post>]>
>>> Post.objects.filter(tags__0_2__contains=['thoughts'])
>>> Post.objects.filter(tags__0_2__contains=["thoughts"])
<QuerySet [<Post: First post>, <Post: Second post>]>
.. note::
@ -374,6 +382,7 @@ We will use the following example model::
from django.contrib.postgres.fields import HStoreField
from django.db import models
class Dog(models.Model):
name = models.CharField(max_length=200)
data = HStoreField()
@ -390,17 +399,17 @@ To query based on a given key, you can use that key as the lookup name:
.. code-block:: pycon
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie'})
>>> Dog.objects.create(name="Rufus", data={"breed": "labrador"})
>>> Dog.objects.create(name="Meg", data={"breed": "collie"})
>>> Dog.objects.filter(data__breed='collie')
>>> Dog.objects.filter(data__breed="collie")
<QuerySet [<Dog: Meg>]>
You can chain other lookups after key lookups:
.. code-block:: pycon
>>> Dog.objects.filter(data__breed__contains='l')
>>> Dog.objects.filter(data__breed__contains="l")
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>
or use ``F()`` expressions to annotate a key value. For example:
@ -441,14 +450,14 @@ field. It uses the SQL operator ``@>``. For example:
.. code-block:: pycon
>>> 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.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'})
>>> Dog.objects.filter(data__contains={"owner": "Bob"})
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>
>>> Dog.objects.filter(data__contains={'breed': 'collie'})
>>> Dog.objects.filter(data__contains={"breed": "collie"})
<QuerySet [<Dog: Meg>]>
.. fieldlookup:: hstorefield.contained_by
@ -463,14 +472,14 @@ example:
.. code-block:: pycon
>>> 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.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'})
>>> Dog.objects.filter(data__contained_by={"breed": "collie", "owner": "Bob"})
<QuerySet [<Dog: Meg>, <Dog: Fred>]>
>>> Dog.objects.filter(data__contained_by={'breed': 'collie'})
>>> Dog.objects.filter(data__contained_by={"breed": "collie"})
<QuerySet [<Dog: Fred>]>
.. fieldlookup:: hstorefield.has_key
@ -483,10 +492,10 @@ Returns objects where the given key is in the data. Uses the SQL operator
.. code-block:: pycon
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
>>> 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')
>>> Dog.objects.filter(data__has_key="owner")
<QuerySet [<Dog: Meg>]>
.. fieldlookup:: hstorefield.has_any_keys
@ -499,11 +508,11 @@ operator ``?|``. For example:
.. code-block:: pycon
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
>>> Dog.objects.create(name='Meg', data={'owner': 'Bob'})
>>> Dog.objects.create(name='Fred', data={})
>>> 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'])
>>> Dog.objects.filter(data__has_any_keys=["owner", "breed"])
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>
.. fieldlookup:: hstorefield.has_keys
@ -516,10 +525,10 @@ Returns objects where all of the given keys are in the data. Uses the SQL operat
.. code-block:: pycon
>>> Dog.objects.create(name='Rufus', data={})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
>>> Dog.objects.create(name="Rufus", data={})
>>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": "Bob"})
>>> Dog.objects.filter(data__has_keys=['breed', 'owner'])
>>> Dog.objects.filter(data__has_keys=["breed", "owner"])
<QuerySet [<Dog: Meg>]>
.. fieldlookup:: hstorefield.keys
@ -535,10 +544,10 @@ in conjunction with lookups on
.. code-block:: pycon
>>> Dog.objects.create(name='Rufus', data={'toy': 'bone'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
>>> 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'])
>>> Dog.objects.filter(data__keys__overlap=["breed", "toy"])
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>
.. fieldlookup:: hstorefield.values
@ -554,10 +563,10 @@ using in conjunction with lookups on
.. code-block:: pycon
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
>>> 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'])
>>> Dog.objects.filter(data__values__contains=["collie"])
<QuerySet [<Dog: Meg>]>
.. _range-fields:
@ -666,6 +675,7 @@ model::
from django.contrib.postgres.fields import IntegerRangeField
from django.db import models
class Event(models.Model):
name = models.CharField(max_length=200)
ages = IntegerRangeField()
@ -681,8 +691,10 @@ We will also use the following example objects:
>>> 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))
>>> 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)
... )
and ``NumericRange``:
@ -945,16 +957,16 @@ corresponding lookups.
.. code-block:: python
class RangeOperators:
EQUAL = '='
NOT_EQUAL = '<>'
CONTAINS = '@>'
CONTAINED_BY = '<@'
OVERLAPS = '&&'
FULLY_LT = '<<'
FULLY_GT = '>>'
NOT_LT = '&>'
NOT_GT = '&<'
ADJACENT_TO = '-|-'
EQUAL = "="
NOT_EQUAL = "<>"
CONTAINS = "@>"
CONTAINED_BY = "<@"
OVERLAPS = "&&"
FULLY_LT = "<<"
FULLY_GT = ">>"
NOT_LT = "&>"
NOT_GT = "&<"
ADJACENT_TO = "-|-"
RangeBoundary() expressions
---------------------------

View file

@ -32,14 +32,15 @@ Fields
>>> class NumberListForm(forms.Form):
... numbers = SimpleArrayField(forms.IntegerField())
...
>>> form = NumberListForm({'numbers': '1,2,3'})
>>> form = NumberListForm({"numbers": "1,2,3"})
>>> form.is_valid()
True
>>> form.cleaned_data
{'numbers': [1, 2, 3]}
>>> form = NumberListForm({'numbers': '1,2,a'})
>>> form = NumberListForm({"numbers": "1,2,a"})
>>> form.is_valid()
False
@ -55,9 +56,10 @@ Fields
>>> from django.contrib.postgres.forms import SimpleArrayField
>>> class GridForm(forms.Form):
... places = SimpleArrayField(SimpleArrayField(IntegerField()), delimiter='|')
... places = SimpleArrayField(SimpleArrayField(IntegerField()), delimiter="|")
...
>>> form = GridForm({'places': '1,2|2,1|4,3'})
>>> form = GridForm({"places": "1,2|2,1|4,3"})
>>> form.is_valid()
True
>>> form.cleaned_data
@ -115,31 +117,31 @@ Fields
SplitArrayField(IntegerField(required=True), size=3, remove_trailing_nulls=False)
['1', '2', '3'] # -> [1, 2, 3]
['1', '2', ''] # -> ValidationError - third entry required.
['1', '', '3'] # -> ValidationError - second entry required.
['', '2', ''] # -> ValidationError - first and third entries required.
["1", "2", "3"] # -> [1, 2, 3]
["1", "2", ""] # -> ValidationError - third entry required.
["1", "", "3"] # -> ValidationError - second entry required.
["", "2", ""] # -> ValidationError - first and third entries required.
SplitArrayField(IntegerField(required=False), size=3, remove_trailing_nulls=False)
['1', '2', '3'] # -> [1, 2, 3]
['1', '2', ''] # -> [1, 2, None]
['1', '', '3'] # -> [1, None, 3]
['', '2', ''] # -> [None, 2, None]
["1", "2", "3"] # -> [1, 2, 3]
["1", "2", ""] # -> [1, 2, None]
["1", "", "3"] # -> [1, None, 3]
["", "2", ""] # -> [None, 2, None]
SplitArrayField(IntegerField(required=True), size=3, remove_trailing_nulls=True)
['1', '2', '3'] # -> [1, 2, 3]
['1', '2', ''] # -> [1, 2]
['1', '', '3'] # -> ValidationError - second entry required.
['', '2', ''] # -> ValidationError - first entry required.
["1", "2", "3"] # -> [1, 2, 3]
["1", "2", ""] # -> [1, 2]
["1", "", "3"] # -> ValidationError - second entry required.
["", "2", ""] # -> ValidationError - first entry required.
SplitArrayField(IntegerField(required=False), size=3, remove_trailing_nulls=True)
['1', '2', '3'] # -> [1, 2, 3]
['1', '2', ''] # -> [1, 2]
['1', '', '3'] # -> [1, None, 3]
['', '2', ''] # -> [None, 2]
["1", "2", "3"] # -> [1, 2, 3]
["1", "2", ""] # -> [1, 2]
["1", "", "3"] # -> [1, None, 3]
["", "2", ""] # -> [None, 2]
``HStoreField``
---------------

View file

@ -149,16 +149,16 @@ available from the ``django.contrib.postgres.indexes`` module.
For example::
Index(
OpClass(Lower('username'), name='varchar_pattern_ops'),
name='lower_username_idx',
OpClass(Lower("username"), name="varchar_pattern_ops"),
name="lower_username_idx",
)
creates an index on ``Lower('username')`` using ``varchar_pattern_ops``.
::
UniqueConstraint(
OpClass(Upper('description'), name='text_pattern_ops'),
name='upper_description_unique',
OpClass(Upper("description"), name="text_pattern_ops"),
name="upper_description_unique",
)
creates a unique constraint on ``Upper('description')`` using
@ -166,9 +166,9 @@ available from the ``django.contrib.postgres.indexes`` module.
::
ExclusionConstraint(
name='exclude_overlapping_ops',
name="exclude_overlapping_ops",
expressions=[
(OpClass('circle', name='circle_ops'), RangeOperators.OVERLAPS),
(OpClass("circle", name="circle_ops"), RangeOperators.OVERLAPS),
],
)

View file

@ -53,7 +53,7 @@ The ``trigram_word_similar`` lookup can be used on
.. code-block:: pycon
>>> Sentence.objects.filter(name__trigram_word_similar='Middlesborough')
>>> Sentence.objects.filter(name__trigram_word_similar="Middlesborough")
['<Sentence: Gumby rides on the path of Middlesbrough>']
.. fieldlookup:: trigram_strict_word_similar

View file

@ -22,13 +22,11 @@ For example::
from django.contrib.postgres.operations import HStoreExtension
class Migration(migrations.Migration):
...
operations = [
HStoreExtension(),
...
]
operations = [HStoreExtension(), ...]
The operation skips adding the extension if it already exists.
@ -124,16 +122,17 @@ For example, to create a collation for German phone book ordering::
from django.contrib.postgres.operations import CreateCollation
class Migration(migrations.Migration):
...
operations = [
CreateCollation(
'german_phonebook',
provider='icu',
locale='und-u-ks-level2',
"german_phonebook",
provider="icu",
locale="und-u-ks-level2",
),
...
...,
]
.. class:: CreateCollation(name, locale, *, provider='libc', deterministic=True)

View file

@ -26,7 +26,7 @@ single column in the database. For example:
.. code-block:: pycon
>>> Entry.objects.filter(body_text__search='Cheese')
>>> Entry.objects.filter(body_text__search="Cheese")
[<Entry: Cheese on Toast recipes>, <Entry: Pizza Recipes>]
This creates a ``to_tsvector`` in the database from the ``body_text`` field
@ -50,8 +50,8 @@ To query against both fields, use a ``SearchVector``:
>>> from django.contrib.postgres.search import SearchVector
>>> Entry.objects.annotate(
... search=SearchVector('body_text', 'blog__tagline'),
... ).filter(search='Cheese')
... search=SearchVector("body_text", "blog__tagline"),
... ).filter(search="Cheese")
[<Entry: Cheese on Toast recipes>, <Entry: Pizza Recipes>]
The arguments to ``SearchVector`` can be any
@ -65,8 +65,8 @@ For example:
.. code-block:: pycon
>>> Entry.objects.annotate(
... search=SearchVector('body_text') + SearchVector('blog__tagline'),
... ).filter(search='Cheese')
... search=SearchVector("body_text") + SearchVector("blog__tagline"),
... ).filter(search="Cheese")
[<Entry: Cheese on Toast recipes>, <Entry: Pizza Recipes>]
See :ref:`postgresql-fts-search-configuration` and
@ -107,9 +107,9 @@ Examples:
.. code-block:: pycon
>>> from django.contrib.postgres.search import SearchQuery
>>> SearchQuery('meat') & SearchQuery('cheese') # AND
>>> SearchQuery('meat') | SearchQuery('cheese') # OR
>>> ~SearchQuery('meat') # NOT
>>> SearchQuery("meat") & SearchQuery("cheese") # AND
>>> SearchQuery("meat") | SearchQuery("cheese") # OR
>>> ~SearchQuery("meat") # NOT
See :ref:`postgresql-fts-search-configuration` for an explanation of the
``config`` parameter.
@ -130,9 +130,9 @@ order by relevancy:
.. code-block:: pycon
>>> from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
>>> vector = SearchVector('body_text')
>>> query = SearchQuery('cheese')
>>> Entry.objects.annotate(rank=SearchRank(vector, query)).order_by('-rank')
>>> vector = SearchVector("body_text")
>>> query = SearchQuery("cheese")
>>> Entry.objects.annotate(rank=SearchRank(vector, query)).order_by("-rank")
[<Entry: Cheese on Toast recipes>, <Entry: Pizza recipes>]
See :ref:`postgresql-fts-weighting-queries` for an explanation of the
@ -199,13 +199,13 @@ Usage example:
.. code-block:: pycon
>>> from django.contrib.postgres.search import SearchHeadline, SearchQuery
>>> query = SearchQuery('red tomato')
>>> query = SearchQuery("red tomato")
>>> entry = Entry.objects.annotate(
... headline=SearchHeadline(
... 'body_text',
... "body_text",
... query,
... start_sel='<span>',
... stop_sel='</span>',
... start_sel="<span>",
... stop_sel="</span>",
... ),
... ).get()
>>> print(entry.headline)
@ -229,8 +229,8 @@ different language parsers and dictionaries as defined by the database:
>>> from django.contrib.postgres.search import SearchQuery, SearchVector
>>> Entry.objects.annotate(
... search=SearchVector('body_text', config='french'),
... ).filter(search=SearchQuery('œuf', config='french'))
... search=SearchVector("body_text", config="french"),
... ).filter(search=SearchQuery("œuf", config="french"))
[<Entry: Pain perdu>]
The value of ``config`` could also be stored in another column:
@ -239,8 +239,8 @@ The value of ``config`` could also be stored in another column:
>>> from django.db.models import F
>>> Entry.objects.annotate(
... search=SearchVector('body_text', config=F('blog__language')),
... ).filter(search=SearchQuery('œuf', config=F('blog__language')))
... search=SearchVector("body_text", config=F("blog__language")),
... ).filter(search=SearchQuery("œuf", config=F("blog__language")))
[<Entry: Pain perdu>]
.. _postgresql-fts-weighting-queries:
@ -254,9 +254,13 @@ of various vectors before you combine them:
.. code-block:: pycon
>>> from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
>>> vector = SearchVector('body_text', weight='A') + SearchVector('blog__tagline', weight='B')
>>> query = SearchQuery('cheese')
>>> Entry.objects.annotate(rank=SearchRank(vector, query)).filter(rank__gte=0.3).order_by('rank')
>>> vector = SearchVector("body_text", weight="A") + SearchVector(
... "blog__tagline", weight="B"
... )
>>> query = SearchQuery("cheese")
>>> Entry.objects.annotate(rank=SearchRank(vector, query)).filter(rank__gte=0.3).order_by(
... "rank"
... )
The weight should be one of the following letters: D, C, B, A. By default,
these weights refer to the numbers ``0.1``, ``0.2``, ``0.4``, and ``1.0``,
@ -266,7 +270,7 @@ floats to :class:`SearchRank` as ``weights`` in the same order above:
.. code-block:: pycon
>>> rank = SearchRank(vector, query, weights=[0.2, 0.4, 0.6, 0.8])
>>> Entry.objects.annotate(rank=rank).filter(rank__gte=0.3).order_by('-rank')
>>> Entry.objects.annotate(rank=rank).filter(rank__gte=0.3).order_by("-rank")
Performance
===========
@ -283,8 +287,8 @@ particular model, you can create a functional
the search vector you wish to use. For example::
GinIndex(
SearchVector('body_text', 'headline', config='english'),
name='search_vector_idx',
SearchVector("body_text", "headline", config="english"),
name="search_vector_idx",
)
The PostgreSQL documentation has details on
@ -303,8 +307,8 @@ if it were an annotated ``SearchVector``:
.. code-block:: pycon
>>> Entry.objects.update(search_vector=SearchVector('body_text'))
>>> Entry.objects.filter(search_vector='cheese')
>>> Entry.objects.update(search_vector=SearchVector("body_text"))
>>> Entry.objects.filter(search_vector="cheese")
[<Entry: Cheese on Toast recipes>, <Entry: Pizza recipes>]
.. _PostgreSQL documentation: https://www.postgresql.org/docs/current/textsearch-features.html#TEXTSEARCH-UPDATE-TRIGGERS
@ -336,12 +340,14 @@ Usage example:
.. code-block:: pycon
>>> from django.contrib.postgres.search import TrigramSimilarity
>>> Author.objects.create(name='Katy Stevens')
>>> Author.objects.create(name='Stephen Keats')
>>> test = 'Katie Stephens'
>>> Author.objects.create(name="Katy Stevens")
>>> Author.objects.create(name="Stephen Keats")
>>> test = "Katie Stephens"
>>> Author.objects.annotate(
... similarity=TrigramSimilarity('name', test),
... ).filter(similarity__gt=0.3).order_by('-similarity')
... similarity=TrigramSimilarity("name", test),
... ).filter(
... similarity__gt=0.3
... ).order_by("-similarity")
[<Author: Katy Stevens>, <Author: Stephen Keats>]
``TrigramWordSimilarity``
@ -357,12 +363,14 @@ Usage example:
.. code-block:: pycon
>>> from django.contrib.postgres.search import TrigramWordSimilarity
>>> Author.objects.create(name='Katy Stevens')
>>> Author.objects.create(name='Stephen Keats')
>>> test = 'Kat'
>>> Author.objects.create(name="Katy Stevens")
>>> Author.objects.create(name="Stephen Keats")
>>> test = "Kat"
>>> Author.objects.annotate(
... similarity=TrigramWordSimilarity(test, 'name'),
... ).filter(similarity__gt=0.3).order_by('-similarity')
... similarity=TrigramWordSimilarity(test, "name"),
... ).filter(
... similarity__gt=0.3
... ).order_by("-similarity")
[<Author: Katy Stevens>]
``TrigramStrictWordSimilarity``
@ -390,12 +398,14 @@ Usage example:
.. code-block:: pycon
>>> from django.contrib.postgres.search import TrigramDistance
>>> Author.objects.create(name='Katy Stevens')
>>> Author.objects.create(name='Stephen Keats')
>>> test = 'Katie Stephens'
>>> Author.objects.create(name="Katy Stevens")
>>> Author.objects.create(name="Stephen Keats")
>>> test = "Katie Stephens"
>>> Author.objects.annotate(
... distance=TrigramDistance('name', test),
... ).filter(distance__lte=0.7).order_by('distance')
... distance=TrigramDistance("name", test),
... ).filter(
... distance__lte=0.7
... ).order_by("distance")
[<Author: Katy Stevens>, <Author: Stephen Keats>]
``TrigramWordDistance``
@ -411,12 +421,14 @@ Usage example:
.. code-block:: pycon
>>> from django.contrib.postgres.search import TrigramWordDistance
>>> Author.objects.create(name='Katy Stevens')
>>> Author.objects.create(name='Stephen Keats')
>>> test = 'Kat'
>>> Author.objects.create(name="Katy Stevens")
>>> Author.objects.create(name="Stephen Keats")
>>> test = "Kat"
>>> Author.objects.annotate(
... distance=TrigramWordDistance(test, 'name'),
... ).filter(distance__lte=0.7).order_by('distance')
... distance=TrigramWordDistance(test, "name"),
... ).filter(
... distance__lte=0.7
... ).order_by("distance")
[<Author: Katy Stevens>]
``TrigramStrictWordDistance``