Todos estos campos están disponibles desde el módulo django.contrib.postgres.fields.
Index y Field.db_index ambos crean un índice B-tree, que no es particularmente útil al consultar tipos de datos complejos. Los índices como GinIndex y GistIndex son más adecuados, aunque la elección del índice depende de las consultas que estás utilizando. En general, GiST puede ser una buena opción para los campos de rango <range-fields> y HStoreField, y GIN puede resultar útil para ArrayField.
ArrayField¶Un campo para almacenar listas de datos. La mayoría de los tipos de campos pueden ser utilizados, y pasas otra instancia de campo como el base_field. También puedes especificar un size. ArrayField puede ser anidado para almacenar matrices multidimensionales.
Si le das al campo una default, asegúrate de que sea un llamable como list (para un valor por defecto vacío) o un llamable que devuelve una lista (como una función). Utilizar incorrectamente default=[] crea un valor por defecto mutable compartido entre todas las instancias de ArrayField.
Este es un argumento obligatorio.
Specifica el tipo de datos subyacente y comportamiento para la matriz. Debe ser una instancia de una clase que herede de Field. Por ejemplo, podría ser una IntegerField o una CharField. La mayoría de los tipos de campos están permitidos, con la excepción de aquellos que manejan datos relacionales (ForeignKey, OneToOneField y ManyToManyField) y campos de archivo (FileField y ImageField).
Es posible anidar campos de matriz - puedes especificar una instancia de ArrayField como el campo base. Por ejemplo:
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,
)
La transformación de valores entre la base de datos y el modelo, la validación de los datos y la configuración, así como la serialización, se delegan en el campo base subyacente.
Este es un argumento opcional.
Si se pasa, la matriz tendrá un tamaño máximo tal como se especifica. Esto se pasará a la base de datos, aunque PostgreSQL no aplica la restricción actualmente.
Nota
Cuando anidas ArrayField, ya sea que utilices el parámetro size o no, PostgreSQL requiere que las matrices sean rectangulares:
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],
]
)
Si se requieren formas irregulares, entonces el campo subyacente debe hacerse nulo y los valores deben ser rellenados con None.
ArrayField¶Hay un número de consultas personalizadas y transformaciones para ArrayField. Utilizaremos el siguiente modelo de ejemplo:
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
contiene¶La traducción de los textos es la siguiente:
>>> 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¶Esta es la inversa del lookup contains - los objetos devueltos serán aquellos donde los datos son un subconjunto de los valores pasados. Utiliza el operador SQL <@. Por ejemplo:
>>> 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¶Devuelve objetos donde los datos comparten resultados con los valores pasados. Utiliza el operador SQL &&. Por ejemplo:
>>> 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"])
<QuerySet [<Post: First post>, <Post: Second post>]>
>>> 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"))
<QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>
len¶Devuelve la longitud del array. Los lookups disponibles después de esto son aquellos disponibles para IntegerField. Por ejemplo:
>>> 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>]>
Las transformaciones de índice convierten el índice en el array. Cualquier entero no negativo se puede utilizar. No hay errores si supera la longitud del array size. Los lookups disponibles después de la transformación son aquellos desde el campo base_field. Por ejemplo:
>>> 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 []>
Nota
PostgreSQL utiliza índices 1-basados para campos de arrays al escribir SQL crudo. Sin embargo, estos índices y los utilizados en slices usan índices 0-basados para ser consistentes con Python.
Las transformaciones de slice toman una porción del array. Cualquier dos enteros no negativos pueden ser utilizados, separados por un solo guión bajo. Los lookups disponibles después de la transformación no cambian. Por ejemplo:
>>> 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>]>
Nota
PostgreSQL utiliza índices 1-basado para campos de arrays al escribir SQL crudo. Sin embargo, estas slices y las utilizadas en indexes utilizan índices 0-basados para ser consistentes con Python.
Arrays multidimensionales con índices y slices
PostgreSQL tiene un comportamiento bastante esotérico cuando se usan índices y slices en arrays multidimensionales. Siempre funcionará usar índices para llegar hasta la última información subyacente, pero la mayoría de las otras slices comportarse de manera extraña a nivel de base de datos y no pueden ser soportadas de manera lógica y consistente por Django.
HStoreField¶Un campo para almacenar pares clave-valor. El tipo de dato Python utilizado es un dict. Las claves deben ser cadenas, y los valores pueden ser cadenas o nulos (None en Python).
Para utilizar este campo, necesitarás:
Agregar 'django.contrib.postgres' a tu INSTALLED_APPS.
Configura la extensión hstore en PostgreSQL.
You’ll see an error like can't adapt type 'dict' if you skip the first
step, or type "hstore" does not exist if you skip the second.
Nota
En ocasiones puede ser útil requerir o restringir las claves válidas para un campo determinado. Esto se puede hacer utilizando la KeysValidator.
HStoreField¶Además de la capacidad de consultar por clave, hay una serie de consultas personalizadas disponibles para HStoreField.
Usaremos el siguiente modelo de ejemplo:
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
Para consultar basándote en una clave determinada, puedes utilizar esa clave como nombre de consulta:
>>> 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>]>
Puedes encadenar otras consultas después de las consultas por clave:
>>> Dog.objects.filter(data__breed__contains="l")
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>
o utiliza expresiones F() para anotar el valor de una clave. Por ejemplo:
>>> from django.db.models import F
>>> rufus = Dog.objects.annotate(breed=F("data__breed"))[0]
>>> rufus.breed
'labrador'
Si la clave que deseas consultar coincide con el nombre de otra consulta, debes utilizar la hstorefield.contains consulta en su lugar.
Nota
Los textos traducidos son:
Advertencia
Dado que cualquier cadena podría ser una clave en un valor hstore, cualquier consulta de búsqueda distinta a las listadas a continuación se interpretará como una consulta de búsqueda por clave. No se levantan errores. Ten especial cuidado con los errores de tipado y siempre verifica que tus consultas funcionen como pretendes.
contiene¶La consulta de búsqueda contains está sobrescrita en el campo HStoreField. Los objetos devueltos son aquellos donde las pares clave-valor dados están contenidos todos en el campo. Utiliza el operador SQL @>. Por ejemplo:
>>> 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¶Esto es la inversa de la consulta de búsqueda contains - los objetos devueltos serán aquellos donde las pares clave-valor del objeto son un subconjunto de los en el valor pasado. Utiliza el operador SQL <@. Por ejemplo:
>>> 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>]>
Devuelve objetos donde la clave dada está en los datos. Utiliza el operador SQL ?. Por ejemplo:
>>> 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>]>
Devuelve objetos donde cualquiera de las claves dadas están en los datos. Utiliza el operador SQL ?|. Por ejemplo:
>>> 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>]>
Devuelve objetos donde todas las claves dadas están en los datos. Utiliza el operador SQL ?&. Por ejemplo:
>>> 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¶Devuelve objetos donde el array de claves es el valor dado. Ten en cuenta que el orden no está garantizado para ser confiable, por lo que esta transformación es principalmente útil para usar en conjunto con consultas de búsqueda sobre ArrayField. Utiliza la función SQL akeys(). Por ejemplo:
>>> 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¶Devuelve objetos donde el array de valores es el valor dado. Ten en cuenta que el orden no está garantizado para ser confiable, por lo que esta transformación es principalmente útil para usar en conjunto con consultas de búsqueda sobre ArrayField. Utiliza la función SQL avals(). Por ejemplo:
>>> 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>]>
Hay cinco tipos de campos de rango, correspondientes a los tipos de rango integrados en PostgreSQL. Estos campos se utilizan para almacenar un rango de valores; por ejemplo, los timestamps de inicio y fin de un evento, o el rango de edades que una actividad es adecuada.
Todos los campos de rango se traducen a objetos psycopg Range en Python, pero también aceptan tuplas como entrada si no se necesita información sobre límites. El valor por defecto es el límite inferior incluido y el límite superior excluido, es decir [) (consulte la documentación de PostgreSQL para detalles sobre diferentes límites). Los límites por defecto pueden cambiarse para campos de rango no discretos (DateTimeRangeField y DecimalRangeField) utilizando el argumento default_bounds.
PostgreSQL normaliza un rango con puntos vacíos al rango vacío
Un rango con valores iguales especificados para un límite inferior incluido y un límite superior excluido, como Range(datetime.date(2005, 6, 21), datetime.date(2005, 6, 21)) o [4, 4), no tiene puntos. PostgreSQL normalizará el valor al vacío cuando se guarde en la base de datos y los valores originales de límite se perderán. Consulte la documentación de PostgreSQL para detalles <https://www.postgresql.org/docs/current/rangetypes.html#RANGETYPES-IO>`_.
IntegerRangeField¶Almacena un rango de enteros. Basado en un IntegerField. Representado por un int4range en la base de datos y un django.db.backends.postgresql.psycopg_any.NumericRange en Python.
Independientemente de los límites especificados al guardar los datos, PostgreSQL siempre devuelve un rango en una forma canónica que incluye el límite inferior y excluye el límite superior, es decir [).
BigIntegerRangeField¶Almacena un rango de enteros grandes. Basado en un BigIntegerField. Representado por un int8range en la base de datos y un django.db.backends.postgresql.psycopg_any.NumericRange en Python.
Independientemente de los límites especificados al guardar los datos, PostgreSQL siempre devuelve un rango en una forma canónica que incluye el límite inferior y excluye el límite superior, es decir [).
DecimalRangeField¶Almacena un rango de valores de punto flotante. Basado en un DecimalField. Representado por un numrange en la base de datos y un django.db.backends.postgresql.psycopg_any.NumericRange en Python.
Opcional. El valor de bounds para los inputs de lista y tupla. El valor predeterminado es el límite inferior incluido, el límite superior excluido, es decir [) (consulte la documentación de PostgreSQL para detalles sobre diferentes límites). No se utiliza default_bounds para los inputs django.db.backends.postgresql.psycopg_any.NumericRange.
DateTimeRangeField¶Almacena un rango de timestamps. Basado en un DateTimeField. Representado por un tstzrange en la base de datos y un django.db.backends.postgresql.psycopg_any.DateTimeTZRange en Python.
Opcional. El valor de bounds para los inputs de lista y tupla. El valor predeterminado es el límite inferior incluido, el límite superior excluido, es decir [) (consulte la documentación de PostgreSQL para detalles sobre diferentes límites). No se utiliza default_bounds para los inputs django.db.backends.postgresql.psycopg_any.DateTimeTZRange.
Campo de Fecha Rango¶Almacena un rango de fechas. Basado en un DateField. Representado por un daterange en la base de datos y un django.db.backends.postgresql.psycopg_any.DateRange en Python.
Independientemente de los límites especificados al guardar los datos, PostgreSQL siempre devuelve un rango en una forma canónica que incluye el límite inferior y excluye el límite superior, es decir [).
Hay una serie de consultas personalizadas y transformaciones para campos de rango. Están disponibles en todos los campos anteriores, pero usaremos el siguiente modelo de ejemplo:
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
También utilizaremos los siguientes objetos de ejemplo:
>>> 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)
... )
y NumericRange:
>>> from django.db.backends.postgresql.psycopg_any import NumericRange
Al igual que otros campos PostgreSQL, hay tres operadores estándar de contención: contains, contained_by y overlap, utilizando los operadores SQL @>, <@, y && respectivamente.
contiene¶>>> 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>]>
La función de búsqueda contained_by también está disponible en los tipos no de rango de campos: SmallAutoField, AutoField, BigAutoField, SmallIntegerField, IntegerField, BigIntegerField, DecimalField, FloatField, DateField, y DateTimeField. Por ejemplo:
>>> from django.db.backends.postgresql.psycopg_any 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>]>
Los campos de rango admiten las consultas estándar: lt, gt, lte y gte. Estas no son particularmente útiles - comparan los límites inferiores primero y luego los superiores sólo si es necesario. Esta también es la estrategia utilizada para ordenar por un campo de rango. Es mejor utilizar los operadores específicos de comparación de rango.
fully_lt¶Los rangos devueltos son estrictamente menores que el rango pasado. En otras palabras, todos los puntos en el rango devuelto son menores que todos aquellos en el rango pasado.
>>> Event.objects.filter(ages__fully_lt=NumericRange(11, 15))
<QuerySet [<Event: Soft play>]>
fully_gt¶Los rangos devueltos son estrictamente mayores que el rango pasado. En otras palabras, todos los puntos en el rango devuelto son mayores que todos aquellos en el rango pasado.
>>> Event.objects.filter(ages__fully_gt=NumericRange(11, 15))
<QuerySet [<Event: Pub trip>]>
not_lt¶Los rangos devueltos no contienen ningún punto menor que el rango pasado, es decir, el límite inferior del rango devuelto es al menos el límite inferior del rango pasado.
>>> Event.objects.filter(ages__not_lt=NumericRange(0, 15))
<QuerySet [<Event: Soft play>, <Event: Pub trip>]>
not_gt¶Los rangos devueltos no contienen ningún punto mayor que el rango pasado, es decir, el límite superior del rango devuelto es como máximo el límite superior del rango pasado.
>>> Event.objects.filter(ages__not_gt=NumericRange(3, 10))
<QuerySet [<Event: Soft play>]>
adjacent_to¶Los rangos devueltos comparten un límite con el rango pasado.
>>> Event.objects.filter(ages__adjacent_to=NumericRange(10, 21))
<QuerySet [<Event: Soft play>, <Event: Pub trip>]>
Los campos de rango admiten varias consultas adicionales.
startswith¶Los objetos devueltos tienen el límite inferior dado. Pueden encadenarse a consultas válidas para el campo base.
>>> Event.objects.filter(ages__startswith=21)
<QuerySet [<Event: Pub trip>]>
endswith¶Los objetos devueltos tienen el límite superior dado. Pueden encadenarse a consultas válidas para el campo base.
>>> Event.objects.filter(ages__endswith=10)
<QuerySet [<Event: Soft play>]>
Los objetos devueltos son rangos vacíos. Pueden encadenarse a consultas válidas para un BooleanField.
>>> Event.objects.filter(ages__isempty=True)
<QuerySet []>
lower_inc¶Devuelve objetos que tienen límites inferiores inclusivos o excluyentes, dependiendo del valor booleano pasado. Pueden encadenarse a consultas válidas para un BooleanField.
>>> Event.objects.filter(ages__lower_inc=True)
<QuerySet [<Event: Soft play>, <Event: Pub trip>]>
lower_inf¶Devuelve objetos que tienen un límite inferior ilimitado (infinito) o limitado, dependiendo del valor booleano pasado. Puede ser encadenada a consultas válidas para un BooleanField.
>>> Event.objects.filter(ages__lower_inf=True)
<QuerySet []>
upper_inc¶Devuelve objetos que tienen límites superiores inclusivos o excluyentes, dependiendo del valor booleano pasado. Puede ser encadenada a consultas válidas para un BooleanField.
>>> Event.objects.filter(ages__upper_inc=True)
<QuerySet []>
upper_inf¶Devuelve objetos que tienen un límite superior ilimitado (infinito) o limitado, dependiendo del valor booleano pasado. Puede ser encadenada a consultas válidas para un BooleanField.
>>> Event.objects.filter(ages__upper_inf=True)
<QuerySet [<Event: Pub trip>]>
PostgreSQL permite la definición de tipos de rango personalizados. Las implementaciones de modelos y campos de formulario de Django utilizan clases base a continuación, y psycopg proporciona una register_range() para permitir el uso de tipos de rango personalizados.
Clase base para campos de modelo de rango.
La clase del campo de modelo a utilizar.
El tipo de rango a utilizar.
La clase del campo de formulario a utilizar. Debe ser una subclase de django.contrib.postgres.forms.BaseRangeField.
PostgreSQL proporciona un conjunto de operadores SQL que se pueden usar junto con los tipos de datos de rango (consulte la documentación de PostgreSQL para obtener detalles completos sobre los operadores de rango). Esta clase está diseñada como un método conveniente para evitar errores de escritura. Los nombres de los operadores se superponen con los nombres de las correspondientes consultas.
class RangeOperators:
EQUAL = "="
NOT_EQUAL = "<>"
CONTAINS = "@>"
CONTAINED_BY = "<@"
OVERLAPS = "&&"
FULLY_LT = "<<"
FULLY_GT = ">>"
NOT_LT = "&>"
NOT_GT = "&<"
ADJACENT_TO = "-|-"
Si True (por defecto), la frontera inferior es inclusiva '[', en caso contrario es exclusiva '('.
Si False (por defecto), la frontera superior es exclusiva ')', en caso contrario es inclusiva ']'.
Una expresión RangeBoundary() representa las fronteras del rango. Puede usarse con funciones de rango personalizadas que esperan fronteras, por ejemplo para definir ExclusionConstraint. Consulte la documentación de PostgreSQL para obtener detalles completos.
may 31, 2026