侧边栏壁纸
  • 累计撰写 218 篇文章
  • 累计创建 59 个标签
  • 累计收到 5 条评论

Django 为 PostgreSQL 设计的专有模型字段

barwe
2022-10-08 / 0 评论 / 0 点赞 / 823 阅读 / 2,015 字
温馨提示:
本文最后更新于 2023-06-07,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

django.contrib.postgres.fields提供了几个特殊的 Field 类。

ArrayField

存储数组或者列表数据。

字段定义

class ArrayField(base_field, ...)
  • base_field: 数组的每个元素应该是基本的 Field
    • 常见的基本数据类型对应的 Field 都可以用;不可用的有
      • 表示外键和关系的字段:ForeignKey, OneToOneField, ManyTo ManyField, ...
      • 表示文件或者图像等二进制资源的字段:FileField, ImageField, ...
    • 可以嵌套一个``ArrayField`表示多维数组,嵌套数组必须是一个矩形
  • size: 可选参数,数组的最大长度
  • default: 可选参数,传入list而不是[]将字段默认值设置为空数组

字段查询

假设模型Post有一个数组字段tags

直接判断是否相同:

Post.objects.filter(tags=['kw1', 'kw2'])

contains

post 的 tags 中是否包含某些元素:

Post.objects.filter(tags__contains=['kw1', 'kw2'])

contained_by

post 的 tags 的所有元素是否都被指定数组包含:

Post.objects.filter(tags__contains_by=['kw1', 'kw2', 'kw3'])

overlap

post 的 tags 数组是否与指定数组有重叠:

Post.objects.filter(tags_overlap=['kw1', 'kw2'])

len

数组字段的长度:

Post.objects.filter(tags__len=1)

索引

查找 tags 数组第一个元素值为 kw1 的所有 posts:

Post.objects.filter(tags__0='kw1')

查找 tags 数组第一个元素值为 kw1 的所有 posts(忽略大小写):

Post.objects.filter(tags__0__iexact='KW1')

如果查询的索引超过来了数组的实际大小,则返回空的查询集,而不是报错:

Post.objects.filter(tags__9999='kw')

切片

格式:field__start_end,其中 start 取得到,end 取不到。

Post.objects.filter(tags__0_1)

CIText

创建大小写不敏感的字符串,可以细分为:

  • CICharField: mixin CIText and CharField
  • CIEmailField: mixin CIText and EmailField
  • CITextField: mixin CIText and TextField

HStoreField

存储键值对(dict)的字段,键必须是字符串,值必须是字符串或者None(boolean?)

使用这个字符安需要

  • 为 django 安装 APP:django.contrib.postgres
  • 为 postgresql 安装 hstore 扩展:参考

字段定义

from django.contrib.postgres.fields import HStoreField

class Dog(models.Model):
    name = models.CharField(max_length=200)
    data = HStoreField()
Dog.objects.create(name='Rufus', data={'breed': 'labrador'})

字段查询

索引

Dog.objects.filter(data__breed='collie')
Dog.objects.filter(data__breed__contains='l')

将字典字段的某个属性标记为记录的某个注释信息:

from django.db.models import F
dogs = Dog.objects.annotate(breed=F("data__breed"))

这样 dogs 中的每个成员都拥有 .breed 属性可以直接访问其字典字段值中的 breed 值。

contains

是否包含某个子字典。

contained_by

是否被某个字典包含。

has_key

是否拥有某个键。

has_any_keys

是否拥有指定列表中的任意一个键。

has_keys

是否拥有指定列表中的所有键。

keys

获取所有键的数组。

values

所有值的数组。

RangeField

可以细分为五种具体的类型,与 PostgreSQL 的五种内置类型对应。

  • IntegerRangeField
  • BigIntegerRangeField
  • DecimalRangeField
  • DateTimeRangeField
  • DateRangeField

References

0

评论区