数据库函数Link to this heading

The classes documented below provide a way for users to use functions provided by the underlying database as annotations, aggregations, or filters in Django. Functions are also expressions, so they can be used and combined with other expressions like aggregate functions. See the Func documentation for security considerations.

我们将在每个函数的例子中使用以下模型:

Code
class Author(models.Model):
    name = models.CharField(max_length=50)
    age = models.PositiveIntegerField(null=True, blank=True)
    alias = models.CharField(max_length=50, null=True, blank=True)
    goes_by = models.CharField(max_length=50, null=True, blank=True)

我们通常不建议允许 null=TrueCharField,因为这允许字段有两个 Coalesce,但它对下面的 Coalesce 例子很重要。

比较和转换函数Link to this heading

CastLink to this heading

class Cast(expression, output_field)Link to this definition

强制 expression 的结果类型为 output_field 的类型。

用法示例:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Cast
>>> Author.objects.create(age=25, name="Margaret Smith")
>>> author = Author.objects.annotate(
...     age_as_float=Cast("age", output_field=FloatField()),
... ).get()
>>> print(author.age_as_float)
25.0

CoalesceLink to this heading

class Coalesce(*expressions, **extra)Link to this definition

接受至少两个字段名或表达式的列表,并返回第一个非空值(注意,空字符串不被视为空值)。每个参数必须是同样的类型,因此混合文本和数字将导致数据库错误。

使用示例:

Python console
>>> # Get a screen name from least to most public
>>> from django.db.models import Sum
>>> from django.db.models.functions import Coalesce
>>> Author.objects.create(name="Margaret Smith", goes_by="Maggie")
>>> author = Author.objects.annotate(screen_name=Coalesce("alias", "goes_by", "name")).get()
>>> print(author.screen_name)
Maggie

>>> # Prevent an aggregate Sum() from returning None
>>> # The aggregate default argument uses Coalesce() under the hood.
>>> aggregated = Author.objects.aggregate(
...     combined_age=Sum("age"),
...     combined_age_default=Sum("age", default=0),
...     combined_age_coalesce=Coalesce(Sum("age"), 0),
... )
>>> print(aggregated["combined_age"])
None
>>> print(aggregated["combined_age_default"])
0
>>> print(aggregated["combined_age_coalesce"])
0

CollateLink to this heading

class Collate(expression, collation)Link to this definition

接受一个表达式和一个排序规则名称来进行查询。

例如,在 SQLite 中进行不区分大小写的过滤:

Python console
>>> Author.objects.filter(name=Collate(Value("john"), "nocase"))
<QuerySet [<Author: John>, <Author: john>]>

它还可以用于排序,例如在 PostgreSQL 中:

Python console
>>> Author.objects.order_by(Collate("name", "et-x-icu"))
<QuerySet [<Author: Ursula>, <Author: Veronika>, <Author: Ülle>]>

GreatestLink to this heading

class Greatest(*expressions, **extra)Link to this definition

接受至少两个字段名或表达式的列表,并返回最大的值。每个参数必须是同样的类型,所以混合文本和数字会导致数据库错误。

使用实例:

Code
class Blog(models.Model):
    body = models.TextField()
    modified = models.DateTimeField(auto_now=True)


class Comment(models.Model):
    body = models.TextField()
    modified = models.DateTimeField(auto_now=True)
    blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
Python console
>>> from django.db.models.functions import Greatest
>>> blog = Blog.objects.create(body="Greatest is the best.")
>>> comment = Comment.objects.create(body="No, Least is better.", blog=blog)
>>> comments = Comment.objects.annotate(last_updated=Greatest("modified", "blog__modified"))
>>> annotated_comment = comments.get()

annotated_comment.last_updated 将是 blog.modifiedcomment.modified 中最近的。

LeastLink to this heading

class Least(*expressions, **extra)Link to this definition

接受至少两个字段名或表达式的列表,并返回最小值。每个参数必须是同样的类型,因此混合文本和数字将导致数据库错误。

NullIfLink to this heading

class NullIf(expression1, expression2)Link to this definition

接受两个表达式,如果相等则返回 None,否则返回 expression1

日期函数Link to this heading

我们将在每个函数的例子中使用以下模型:

Code
class Experiment(models.Model):
    start_datetime = models.DateTimeField()
    start_date = models.DateField(null=True, blank=True)
    start_time = models.TimeField(null=True, blank=True)
    end_datetime = models.DateTimeField(null=True, blank=True)
    end_date = models.DateField(null=True, blank=True)
    end_time = models.TimeField(null=True, blank=True)

ExtractLink to this heading

class Extract(expression, lookup_name=None, tzinfo=None, **extra)Link to this definition

提取日期的一个组成部分作为一个数字。

接受表示 DateFieldDateTimeFieldTimeFieldDurationFieldexpression,以及一个 lookup_name,并将被 lookup_name 引用的日期部分作为 IntegerField 返回。Django 通常使用数据库的 extract 函数,因此您可以使用数据库支持的任何 lookup_name。可以传递一个 tzinfo 子类,通常由 zoneinfo 提供,以在特定时区中提取值。

给定日期时间 2015-06-15 23:30:01.000321+00:00,内置的 lookup_name 返回。

  • "year": 2015

  • "iso_year": 2015

  • "quarter": 2

  • "month": 6

  • "day": 15

  • "week": 25

  • "week_day": 2

  • "iso_week_day": 1

  • "hour": 23

  • "minute": 30

  • "second": 1

如果在 Django 中使用了不同的时区,比如 Australia/Melbourne ,那么在提取值之前,日期时间会被转换为该时区。在上面的例子中,墨尔本的时区偏移是 +10:00。当这个时区被激活时,返回的值将与上述相同,除了:

  • "day": 16

  • "week_day": 3

  • "iso_week_day": 2

  • "hour": 9

上面的每个 lookup_name 都有一个相应的 Extract 子类(下面列出的),通常应该用这个子类来代替比较啰嗦的等价物,例如,使用 ExtractYear(...) 而不是 Extract(...,lookup_name='year')

用法示例:

Python console
>>> from datetime import datetime
>>> from django.db.models.functions import Extract
>>> start = datetime(2015, 6, 15)
>>> end = datetime(2015, 7, 2)
>>> Experiment.objects.create(
...     start_datetime=start, start_date=start.date(), end_datetime=end, end_date=end.date()
... )
>>> # Add the experiment start year as a field in the QuerySet.
>>> experiment = Experiment.objects.annotate(
...     start_year=Extract("start_datetime", "year")
... ).get()
>>> experiment.start_year
2015
>>> # How many experiments completed in the same year in which they started?
>>> Experiment.objects.filter(start_datetime__year=Extract("end_datetime", "year")).count()
1

DateField 提取Link to this heading

class ExtractYear(expression, tzinfo=None, **extra)Link to this definition
lookup_name = 'year'
class ExtractIsoYear(expression, tzinfo=None, **extra)Link to this definition

返回 ISO-8601 的周号年份。

lookup_name = 'iso_year'
class ExtractMonth(expression, tzinfo=None, **extra)Link to this definition
lookup_name = 'month'
class ExtractDay(expression, tzinfo=None, **extra)Link to this definition
lookup_name = 'day'
class ExtractWeekDay(expression, tzinfo=None, **extra)Link to this definition
lookup_name = 'week_day'
class ExtractIsoWeekDay(expression, tzinfo=None, **extra)Link to this definition

返回 ISO-8601 的星期日,第 1 天是星期一,第 7 天是星期天。

lookup_name = 'iso_week_day'
class ExtractWeek(expression, tzinfo=None, **extra)Link to this definition
lookup_name = 'week'
class ExtractQuarter(expression, tzinfo=None, **extra)Link to this definition
lookup_name = 'quarter'

这些类在逻辑上等同于 Extract('date_field', lookup_name)。每个类也是一个 TransformDateFieldDateTimeField 上注册为 __(lookup_name)`,例如 __year

由于 DateField 不包含时间组件,因此只能使用处理日期部分的 Extract 子类与 DateField 一起使用:

Python console
>>> from datetime import UTC, datetime
>>> from django.db.models.functions import (
...     ExtractDay,
...     ExtractMonth,
...     ExtractQuarter,
...     ExtractWeek,
...     ExtractIsoWeekDay,
...     ExtractWeekDay,
...     ExtractIsoYear,
...     ExtractYear,
... )
>>> start_2015 = datetime(2015, 6, 15, 23, 30, 1, tzinfo=UTC)
>>> end_2015 = datetime(2015, 6, 16, 13, 11, 27, tzinfo=UTC)
>>> Experiment.objects.create(
...     start_datetime=start_2015,
...     start_date=start_2015.date(),
...     end_datetime=end_2015,
...     end_date=end_2015.date(),
... )
>>> Experiment.objects.annotate(
...     year=ExtractYear("start_date"),
...     isoyear=ExtractIsoYear("start_date"),
...     quarter=ExtractQuarter("start_date"),
...     month=ExtractMonth("start_date"),
...     week=ExtractWeek("start_date"),
...     day=ExtractDay("start_date"),
...     weekday=ExtractWeekDay("start_date"),
...     isoweekday=ExtractIsoWeekDay("start_date"),
... ).values(
...     "year",
...     "isoyear",
...     "quarter",
...     "month",
...     "week",
...     "day",
...     "weekday",
...     "isoweekday",
... ).get(
...     end_date__year=ExtractYear("start_date")
... )
{'year': 2015, 'isoyear': 2015, 'quarter': 2, 'month': 6, 'week': 25,
 'day': 15, 'weekday': 2, 'isoweekday': 1}

DateTimeField 提取Link to this heading

除以下内容外,上述 DateField 的所有提取物也可用于``DateTimeField``。

class ExtractHour(expression, tzinfo=None, **extra)Link to this definition
lookup_name = 'hour'
class ExtractMinute(expression, tzinfo=None, **extra)Link to this definition
lookup_name = 'minute'
class ExtractSecond(expression, tzinfo=None, **extra)Link to this definition
lookup_name = 'second'

这些类在逻辑上等同于 Extract('datetime_field', lookup_name)。每个类也是一个 TransformDateTimeField 上注册为 __(lookup_name),例如 __minute

DateTimeField 例子:

Python console
>>> from datetime import UTC, datetime
>>> from django.db.models.functions import (
...     ExtractDay,
...     ExtractHour,
...     ExtractMinute,
...     ExtractMonth,
...     ExtractQuarter,
...     ExtractSecond,
...     ExtractWeek,
...     ExtractIsoWeekDay,
...     ExtractWeekDay,
...     ExtractIsoYear,
...     ExtractYear,
... )
>>> start_2015 = datetime(2015, 6, 15, 23, 30, 1, tzinfo=UTC)
>>> end_2015 = datetime(2015, 6, 16, 13, 11, 27, tzinfo=UTC)
>>> Experiment.objects.create(
...     start_datetime=start_2015,
...     start_date=start_2015.date(),
...     end_datetime=end_2015,
...     end_date=end_2015.date(),
... )
>>> Experiment.objects.annotate(
...     year=ExtractYear("start_datetime"),
...     isoyear=ExtractIsoYear("start_datetime"),
...     quarter=ExtractQuarter("start_datetime"),
...     month=ExtractMonth("start_datetime"),
...     week=ExtractWeek("start_datetime"),
...     day=ExtractDay("start_datetime"),
...     weekday=ExtractWeekDay("start_datetime"),
...     isoweekday=ExtractIsoWeekDay("start_datetime"),
...     hour=ExtractHour("start_datetime"),
...     minute=ExtractMinute("start_datetime"),
...     second=ExtractSecond("start_datetime"),
... ).values(
...     "year",
...     "isoyear",
...     "month",
...     "week",
...     "day",
...     "weekday",
...     "isoweekday",
...     "hour",
...     "minute",
...     "second",
... ).get(
...     end_datetime__year=ExtractYear("start_datetime")
... )
{'year': 2015, 'isoyear': 2015, 'quarter': 2, 'month': 6, 'week': 25,
 'day': 15, 'weekday': 2, 'isoweekday': 1, 'hour': 23, 'minute': 30,
 'second': 1}

USE_TZ 设置为 True 时,日期时间将以 UTC 格式存储在数据库中。如果 Django 中有不同的时区激活,那么在提取值之前,日期时间将被转换为该时区。下面的示例将日期时间转换为墨尔本时区(UTC +10:00),这将改变返回的日期、工作日和小时值:

Python console
>>> from django.utils import timezone
>>> import zoneinfo
>>> melb = zoneinfo.ZoneInfo("Australia/Melbourne")  # UTC+10:00
>>> with timezone.override(melb):
...     Experiment.objects.annotate(
...         day=ExtractDay("start_datetime"),
...         weekday=ExtractWeekDay("start_datetime"),
...         isoweekday=ExtractIsoWeekDay("start_datetime"),
...         hour=ExtractHour("start_datetime"),
...     ).values("day", "weekday", "isoweekday", "hour").get(
...         end_datetime__year=ExtractYear("start_datetime"),
...     )
...
{'day': 16, 'weekday': 3, 'isoweekday': 2, 'hour': 9}

显式传递时区给 Extract 函数的行为与上述相同,并优先于激活的时区:

Python console
>>> import zoneinfo
>>> melb = zoneinfo.ZoneInfo("Australia/Melbourne")
>>> Experiment.objects.annotate(
...     day=ExtractDay("start_datetime", tzinfo=melb),
...     weekday=ExtractWeekDay("start_datetime", tzinfo=melb),
...     isoweekday=ExtractIsoWeekDay("start_datetime", tzinfo=melb),
...     hour=ExtractHour("start_datetime", tzinfo=melb),
... ).values("day", "weekday", "isoweekday", "hour").get(
...     end_datetime__year=ExtractYear("start_datetime"),
... )
{'day': 16, 'weekday': 3, 'isoweekday': 2, 'hour': 9}

NowLink to this heading

class NowLink to this definition

返回数据库服务器执行查询时的当前日期和时间,通常使用 SQL CURRENT_TIMESTAMP

用法示例:

Python console
>>> from django.db.models.functions import Now
>>> Article.objects.filter(published__lte=Now())
<QuerySet [<Article: How to Django>]>

TruncLink to this heading

class Trunc(expression, kind, output_field=None, tzinfo=None, **extra)Link to this definition

将一个日期截断到一个重要的部分。

当你只关心某事是否发生在某年、某小时或某天,而不关心确切的秒数时,那么 Trunc (及其子类)可以用来过滤或汇总你的数据。例如,你可以使用 Trunc 来计算每天的销售数量。

Trunc 接受一个表示 DateFieldTimeFieldDateTimeFieldexpression,一个表示日期或时间部分的 kind,以及一个 output_field,可以是 DateTimeField()TimeField()DateField()。它根据 output_field 返回一个日期时间、日期或时间,其中字段最多到 kind 设置为其最小值。如果省略了 output_field,它将默认为 expressionoutput_field。可以传递一个 tzinfo 子类,通常由 zoneinfo 提供,以在特定时区中截断值。

给定日期时间 2015-06-15 14:30:50.000321+00:00,内置 kind 返回:

  • "year": 2015-01-01 00:00:00+00:00

  • "quarter": 2015-04-01 00:00:00+00:00

  • "month": 2015-06-01 00:00:00+00:00

  • "week": 2015-06-15 00:00:00+00:00

  • "day": 2015-06-15 00:00:00+00:00

  • "hour": 2015-06-15 14:00:00+00:00

  • "minute": 2015-06-15 14:30:00+00:00

  • "second": 2015-06-15 14:30:50+00:00

如果在 Django 中使用了不同的时区,比如 Australia/Melbourne,那么日期时间会在被截断之前转换为新的时区。在上面的例子中,墨尔本的时区偏移是 +10:00。当这个时区被激活时,返回的值将是:

  • "year": 2015-01-01 00:00:00+11:00

  • "quarter": 2015-04-01 00:00:00+11:00

  • "month": 2015-06-01 00:00:00+10:00

  • "week": 2015-06-15 00:00:00+10:00

  • "day": 2015-06-16 00:00:00+10:00

  • "hour": 2015-06-16 00:00:00+10:00

  • "minute": 2015-06-16 00:30:00+10:00

  • "second": 2015-06-16 00:30:50+10:00

The year and quarter have an offset of +11:00 because each result falls before the daylight saving time transition.

以上每个 kind 都有一个对应的 Trunc 子类(下面列出的),通常应该用这个子类来代替比较啰嗦的等价物,例如使用 TruncYear(...) 而不是 Trunc(...,kind='year')

子类都被定义为变换,但它们没有注册任何字段,因为查找名称已经被 Extract 子类保留。

用法示例:

Python console
>>> from datetime import datetime
>>> from django.db.models import Count, DateTimeField
>>> from django.db.models.functions import Trunc
>>> Experiment.objects.create(start_datetime=datetime(2015, 6, 15, 14, 30, 50, 321))
>>> Experiment.objects.create(start_datetime=datetime(2015, 6, 15, 14, 40, 2, 123))
>>> Experiment.objects.create(start_datetime=datetime(2015, 12, 25, 10, 5, 27, 999))
>>> experiments_per_day = (
...     Experiment.objects.annotate(
...         start_day=Trunc("start_datetime", "day", output_field=DateTimeField())
...     )
...     .values("start_day")
...     .annotate(experiments=Count("id"))
... )
>>> for exp in experiments_per_day:
...     print(exp["start_day"], exp["experiments"])
...
2015-06-15 00:00:00 2
2015-12-25 00:00:00 1
>>> experiments = Experiment.objects.annotate(
...     start_day=Trunc("start_datetime", "day", output_field=DateTimeField())
... ).filter(start_day=datetime(2015, 6, 15))
>>> for exp in experiments:
...     print(exp.start_datetime)
...
2015-06-15 14:30:50.000321
2015-06-15 14:40:02.000123

DateField 截断Link to this heading

class TruncYear(expression, output_field=None, tzinfo=None, **extra)Link to this definition
kind = 'year'
class TruncMonth(expression, output_field=None, tzinfo=None, **extra)Link to this definition
kind = 'month'
class TruncWeek(expression, output_field=None, tzinfo=None, **extra)Link to this definition

截断到每周一的午夜。

kind = 'week'
class TruncQuarter(expression, output_field=None, tzinfo=None, **extra)Link to this definition
kind = 'quarter'

这些在逻辑上等同于 Trunc('date_field', kind)。它们截断日期的所有部分,直至 kind,允许以较低的精度对日期进行分组或过滤。expression 可以有一个 output_fieldDateFieldDateTimeField

由于 DateField 不包含时间组件,因此只能使用处理日期部分的 Trunc 子类与 DateField 一起使用:

Python console
>>> from datetime import UTC, datetime
>>> from django.db.models import Count
>>> from django.db.models.functions import TruncMonth, TruncYear
>>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=UTC)
>>> start2 = datetime(2015, 6, 15, 14, 40, 2, 123, tzinfo=UTC)
>>> start3 = datetime(2015, 12, 31, 17, 5, 27, 999, tzinfo=UTC)
>>> Experiment.objects.create(start_datetime=start1, start_date=start1.date())
>>> Experiment.objects.create(start_datetime=start2, start_date=start2.date())
>>> Experiment.objects.create(start_datetime=start3, start_date=start3.date())
>>> experiments_per_year = (
...     Experiment.objects.annotate(year=TruncYear("start_date"))
...     .values("year")
...     .annotate(experiments=Count("id"))
... )
>>> for exp in experiments_per_year:
...     print(exp["year"], exp["experiments"])
...
2014-01-01 1
2015-01-01 2

>>> import zoneinfo
>>> melb = zoneinfo.ZoneInfo("Australia/Melbourne")
>>> experiments_per_month = (
...     Experiment.objects.annotate(month=TruncMonth("start_datetime", tzinfo=melb))
...     .values("month")
...     .annotate(experiments=Count("id"))
... )
>>> for exp in experiments_per_month:
...     print(exp["month"], exp["experiments"])
...
2015-06-01 00:00:00+10:00 1
2016-01-01 00:00:00+11:00 1
2014-06-01 00:00:00+10:00 1

DateTimeField 截断Link to this heading

class TruncDate(expression, tzinfo=None, **extra)Link to this definition
lookup_name = 'date'
output_field = DateField()

TruncDateexpression 投射到一个日期,而不是使用内置的 SQL truncate 函数。在 DateTimeField 上,它也被注册为 __date 的转换。

class TruncTime(expression, tzinfo=None, **extra)Link to this definition
lookup_name = 'time'
output_field = TimeField()

TruncTimeexpression 投射到一个时间,而不是使用内置的 SQL truncate 函数。在 DateTimeField 上,它也被注册为 __time 的转换。

class TruncDay(expression, output_field=None, tzinfo=None, **extra)Link to this definition
kind = 'day'
class TruncHour(expression, output_field=None, tzinfo=None, **extra)Link to this definition
kind = 'hour'
class TruncMinute(expression, output_field=None, tzinfo=None, **extra)Link to this definition
kind = 'minute'
class TruncSecond(expression, output_field=None, tzinfo=None, **extra)Link to this definition
kind = 'second'

这些在逻辑上等同于 Trunc('datetime_field', kind)。它们截断日期的所有部分,直至 kind,并允许以较低的精度对日期时间进行分组或过滤。expression 必须有一个 output_fieldDateTimeField

用法示例:

Python console
>>> from datetime import UTC, date, datetime
>>> from django.db.models import Count
>>> from django.db.models.functions import (
...     TruncDate,
...     TruncDay,
...     TruncHour,
...     TruncMinute,
...     TruncSecond,
... )
>>> import zoneinfo
>>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=UTC)
>>> Experiment.objects.create(start_datetime=start1, start_date=start1.date())
>>> melb = zoneinfo.ZoneInfo("Australia/Melbourne")
>>> Experiment.objects.annotate(
...     date=TruncDate("start_datetime"),
...     day=TruncDay("start_datetime", tzinfo=melb),
...     hour=TruncHour("start_datetime", tzinfo=melb),
...     minute=TruncMinute("start_datetime"),
...     second=TruncSecond("start_datetime"),
... ).values("date", "day", "hour", "minute", "second").get()
{'date': datetime.date(2014, 6, 15),
 'day': datetime.datetime(2014, 6, 16, 0, 0, tzinfo=zoneinfo.ZoneInfo('Australia/Melbourne')),
 'hour': datetime.datetime(2014, 6, 16, 0, 0, tzinfo=zoneinfo.ZoneInfo('Australia/Melbourne')),
 'minute': 'minute': datetime.datetime(2014, 6, 15, 14, 30, tzinfo=UTC),
 'second': datetime.datetime(2014, 6, 15, 14, 30, 50, tzinfo=UTC)
}

TimeField 截断Link to this heading

class TruncHour(expression, output_field=None, tzinfo=None, **extra)
kind = 'hour'
class TruncMinute(expression, output_field=None, tzinfo=None, **extra)
kind = 'minute'
class TruncSecond(expression, output_field=None, tzinfo=None, **extra)
kind = 'second'

这些在逻辑上等同于 Trunc('time_field', kind)。它们截断时间的所有部分,直至 kind,这就允许以较低的精度对时间进行分组或过滤。expression 可以有一个 output_fieldTimeFieldDateTimeField

由于 TimeField 不包含日期组件,因此只能使用处理时间部分的 Trunc 子类与 TimeField 一起使用:

Python console
>>> from datetime import UTC, datetime
>>> from django.db.models import Count, TimeField
>>> from django.db.models.functions import TruncHour
>>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=UTC)
>>> start2 = datetime(2014, 6, 15, 14, 40, 2, 123, tzinfo=UTC)
>>> start3 = datetime(2015, 12, 31, 17, 5, 27, 999, tzinfo=UTC)
>>> Experiment.objects.create(start_datetime=start1, start_time=start1.time())
>>> Experiment.objects.create(start_datetime=start2, start_time=start2.time())
>>> Experiment.objects.create(start_datetime=start3, start_time=start3.time())
>>> experiments_per_hour = (
...     Experiment.objects.annotate(
...         hour=TruncHour("start_datetime", output_field=TimeField()),
...     )
...     .values("hour")
...     .annotate(experiments=Count("id"))
... )
>>> for exp in experiments_per_hour:
...     print(exp["hour"], exp["experiments"])
...
14:00:00 2
17:00:00 1

>>> import zoneinfo
>>> melb = zoneinfo.ZoneInfo("Australia/Melbourne")
>>> experiments_per_hour = (
...     Experiment.objects.annotate(
...         hour=TruncHour("start_datetime", tzinfo=melb),
...     )
...     .values("hour")
...     .annotate(experiments=Count("id"))
... )
>>> for exp in experiments_per_hour:
...     print(exp["hour"], exp["experiments"])
...
2014-06-16 00:00:00+10:00 2
2016-01-01 04:00:00+11:00 1

JSON FunctionsLink to this heading

JSONArrayLink to this heading

class JSONArray(*expressions)Link to this definition

Accepts a list of field names or expressions and returns a JSON array containing those values.

用法示例:

Python console
>>> from django.db.models import F
>>> from django.db.models.functions import JSONArray, Lower
>>> Author.objects.create(name="Margaret Smith", alias="msmith", age=25)
>>> author = Author.objects.annotate(
...     json_array=JSONArray(
...         Lower("name"),
...         "alias",
...         F("age") * 2,
...     )
... ).get()
>>> author.json_array
['margaret smith', 'msmith', 50]

JSONObjectLink to this heading

class JSONObject(**fields)Link to this definition

接受一组键值对,并返回一个包含这些键值对的 JSON 对象。

用法示例:

Python console
>>> from django.db.models import F
>>> from django.db.models.functions import JSONObject, Lower
>>> Author.objects.create(name="Margaret Smith", alias="msmith", age=25)
>>> author = Author.objects.annotate(
...     json_object=JSONObject(
...         name=Lower("name"),
...         alias="alias",
...         age=F("age") * 2,
...     )
... ).get()
>>> author.json_object
{'name': 'margaret smith', 'alias': 'msmith', 'age': 50}

数学函数Link to this heading

我们将在数学函数实例中使用以下模型:

Code
class Vector(models.Model):
    x = models.FloatField()
    y = models.FloatField()

AbsLink to this heading

class Abs(expression, **extra)Link to this definition

返回一个数值字段或表达式的绝对值。

用法示例:

Python console
>>> from django.db.models.functions import Abs
>>> Vector.objects.create(x=-0.5, y=1.1)
>>> vector = Vector.objects.annotate(x_abs=Abs("x"), y_abs=Abs("y")).get()
>>> vector.x_abs, vector.y_abs
(0.5, 1.1)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Abs
>>> FloatField.register_lookup(Abs)
>>> # Get vectors inside the unit cube
>>> vectors = Vector.objects.filter(x__abs__lt=1, y__abs__lt=1)

ACosLink to this heading

class ACos(expression, **extra)Link to this definition

返回一个数值字段或表达式的余弦值。表达式的值必须在 -1 到 1 的范围内。

用法示例:

Python console
>>> from django.db.models.functions import ACos
>>> Vector.objects.create(x=0.5, y=-0.9)
>>> vector = Vector.objects.annotate(x_acos=ACos("x"), y_acos=ACos("y")).get()
>>> vector.x_acos, vector.y_acos
(1.0471975511965979, 2.6905658417935308)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import ACos
>>> FloatField.register_lookup(ACos)
>>> # Get vectors whose arccosine is less than 1
>>> vectors = Vector.objects.filter(x__acos__lt=1, y__acos__lt=1)

ASinLink to this heading

class ASin(expression, **extra)Link to this definition

返回一个数值字段或表达式的正弦值。表达式的值必须在 -1 到 1 的范围内。

用法示例:

Python console
>>> from django.db.models.functions import ASin
>>> Vector.objects.create(x=0, y=1)
>>> vector = Vector.objects.annotate(x_asin=ASin("x"), y_asin=ASin("y")).get()
>>> vector.x_asin, vector.y_asin
(0.0, 1.5707963267948966)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import ASin
>>> FloatField.register_lookup(ASin)
>>> # Get vectors whose arcsine is less than 1
>>> vectors = Vector.objects.filter(x__asin__lt=1, y__asin__lt=1)

ATanLink to this heading

class ATan(expression, **extra)Link to this definition

返回一个数值字段或表达式的正切值。

用法示例:

Python console
>>> from django.db.models.functions import ATan
>>> Vector.objects.create(x=3.12, y=6.987)
>>> vector = Vector.objects.annotate(x_atan=ATan("x"), y_atan=ATan("y")).get()
>>> vector.x_atan, vector.y_atan
(1.2606282660069106, 1.428638798133829)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import ATan
>>> FloatField.register_lookup(ATan)
>>> # Get vectors whose arctangent is less than 2
>>> vectors = Vector.objects.filter(x__atan__lt=2, y__atan__lt=2)

ATan2Link to this heading

class ATan2(expression1, expression2, **extra)Link to this definition

返回 expression1 / expression2 的正切值。

用法示例:

Python console
>>> from django.db.models.functions import ATan2
>>> Vector.objects.create(x=2.5, y=1.9)
>>> vector = Vector.objects.annotate(atan2=ATan2("x", "y")).get()
>>> vector.atan2
0.9209258773829491

CeilLink to this heading

class Ceil(expression, **extra)Link to this definition

返回大于或等于一个数值字段或表达式的最小整数。

用法示例:

Python console
>>> from django.db.models.functions import Ceil
>>> Vector.objects.create(x=3.12, y=7.0)
>>> vector = Vector.objects.annotate(x_ceil=Ceil("x"), y_ceil=Ceil("y")).get()
>>> vector.x_ceil, vector.y_ceil
(4.0, 7.0)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Ceil
>>> FloatField.register_lookup(Ceil)
>>> # Get vectors whose ceil is less than 10
>>> vectors = Vector.objects.filter(x__ceil__lt=10, y__ceil__lt=10)

CosLink to this heading

class Cos(expression, **extra)Link to this definition

返回一个数值字段或表达式的余弦值。

用法示例:

Python console
>>> from django.db.models.functions import Cos
>>> Vector.objects.create(x=-8.0, y=3.1415926)
>>> vector = Vector.objects.annotate(x_cos=Cos("x"), y_cos=Cos("y")).get()
>>> vector.x_cos, vector.y_cos
(-0.14550003380861354, -0.9999999999999986)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Cos
>>> FloatField.register_lookup(Cos)
>>> # Get vectors whose cosine is less than 0.5
>>> vectors = Vector.objects.filter(x__cos__lt=0.5, y__cos__lt=0.5)

CotLink to this heading

class Cot(expression, **extra)Link to this definition

返回数值字段或表达式的正切值。

用法示例:

Python console
>>> from django.db.models.functions import Cot
>>> Vector.objects.create(x=12.0, y=1.0)
>>> vector = Vector.objects.annotate(x_cot=Cot("x"), y_cot=Cot("y")).get()
>>> vector.x_cot, vector.y_cot
(-1.5726734063976826, 0.642092615934331)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Cot
>>> FloatField.register_lookup(Cot)
>>> # Get vectors whose cotangent is less than 1
>>> vectors = Vector.objects.filter(x__cot__lt=1, y__cot__lt=1)

DegreesLink to this heading

class Degrees(expression, **extra)Link to this definition

将数值字段或表达式从弧度转换为度。

用法示例:

Python console
>>> from django.db.models.functions import Degrees
>>> Vector.objects.create(x=-1.57, y=3.14)
>>> vector = Vector.objects.annotate(x_d=Degrees("x"), y_d=Degrees("y")).get()
>>> vector.x_d, vector.y_d
(-89.95437383553924, 179.9087476710785)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Degrees
>>> FloatField.register_lookup(Degrees)
>>> # Get vectors whose degrees are less than 360
>>> vectors = Vector.objects.filter(x__degrees__lt=360, y__degrees__lt=360)

ExpLink to this heading

class Exp(expression, **extra)Link to this definition

返回 e (自然对数基数)的值,将其升为一个数值字段或表达式的幂。

用法示例:

Python console
>>> from django.db.models.functions import Exp
>>> Vector.objects.create(x=5.4, y=-2.0)
>>> vector = Vector.objects.annotate(x_exp=Exp("x"), y_exp=Exp("y")).get()
>>> vector.x_exp, vector.y_exp
(221.40641620418717, 0.1353352832366127)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Exp
>>> FloatField.register_lookup(Exp)
>>> # Get vectors whose exp() is greater than 10
>>> vectors = Vector.objects.filter(x__exp__gt=10, y__exp__gt=10)

FloorLink to this heading

class Floor(expression, **extra)Link to this definition

返回不大于数值字段或表达式的最大整数值。

用法示例:

Python console
>>> from django.db.models.functions import Floor
>>> Vector.objects.create(x=5.4, y=-2.3)
>>> vector = Vector.objects.annotate(x_floor=Floor("x"), y_floor=Floor("y")).get()
>>> vector.x_floor, vector.y_floor
(5.0, -3.0)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Floor
>>> FloatField.register_lookup(Floor)
>>> # Get vectors whose floor() is greater than 10
>>> vectors = Vector.objects.filter(x__floor__gt=10, y__floor__gt=10)

LnLink to this heading

class Ln(expression, **extra)Link to this definition

返回一个数值字段或表达式的自然对数。

用法示例:

Python console
>>> from django.db.models.functions import Ln
>>> Vector.objects.create(x=5.4, y=233.0)
>>> vector = Vector.objects.annotate(x_ln=Ln("x"), y_ln=Ln("y")).get()
>>> vector.x_ln, vector.y_ln
(1.6863989535702288, 5.4510384535657)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Ln
>>> FloatField.register_lookup(Ln)
>>> # Get vectors whose value greater than e
>>> vectors = Vector.objects.filter(x__ln__gt=1, y__ln__gt=1)

LogLink to this heading

class Log(expression1, expression2, **extra)Link to this definition

接受两个数值字段或表达式,并返回第二个数以第一个数为底的对数。

用法示例:

Python console
>>> from django.db.models.functions import Log
>>> Vector.objects.create(x=2.0, y=4.0)
>>> vector = Vector.objects.annotate(log=Log("x", "y")).get()
>>> vector.log
2.0

ModLink to this heading

class Mod(expression1, expression2, **extra)Link to this definition

接受两个数值字段或表达式,并返回第一个字段除以第二个字段的余数(模数运算)。

用法示例:

Python console
>>> from django.db.models.functions import Mod
>>> Vector.objects.create(x=5.4, y=2.3)
>>> vector = Vector.objects.annotate(mod=Mod("x", "y")).get()
>>> vector.mod
0.8

PiLink to this heading

class Pi(**extra)Link to this definition

返回数学常数 π 的值。

PowerLink to this heading

class Power(expression1, expression2, **extra)Link to this definition

接受两个数值字段或表达式,并将第一个字段的值提高到第二个字段的幂。

用法示例:

Python console
>>> from django.db.models.functions import Power
>>> Vector.objects.create(x=2, y=-2)
>>> vector = Vector.objects.annotate(power=Power("x", "y")).get()
>>> vector.power
0.25

RadiansLink to this heading

class Radians(expression, **extra)Link to this definition

将数值字段或表达式从度数转换为弧度。

用法示例:

Python console
>>> from django.db.models.functions import Radians
>>> Vector.objects.create(x=-90, y=180)
>>> vector = Vector.objects.annotate(x_r=Radians("x"), y_r=Radians("y")).get()
>>> vector.x_r, vector.y_r
(-1.5707963267948966, 3.141592653589793)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Radians
>>> FloatField.register_lookup(Radians)
>>> # Get vectors whose radians are less than 1
>>> vectors = Vector.objects.filter(x__radians__lt=1, y__radians__lt=1)

RandomLink to this heading

class Random(**extra)Link to this definition

返回 0.0 x < 1.0 范围内的随机值。

RoundLink to this heading

class Round(expression, precision=0, **extra)Link to this definition

将数值字段或表达式四舍五入到指定的小数位数 precision (必须为整数)。默认情况下,它会四舍五入到最接近的整数。半数值是向上还是向下舍入取决于数据库。

用法示例:

Python console
>>> from django.db.models.functions import Round
>>> Vector.objects.create(x=5.4, y=-2.37)
>>> vector = Vector.objects.annotate(x_r=Round("x"), y_r=Round("y", precision=1)).get()
>>> vector.x_r, vector.y_r
(5.0, -2.4)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Round
>>> FloatField.register_lookup(Round)
>>> # Get vectors whose round() is less than 20
>>> vectors = Vector.objects.filter(x__round__lt=20, y__round__lt=20)

SignLink to this heading

class Sign(expression, **extra)Link to this definition

返回一个数字字段或表达式的符号(-1,0,1)。

用法示例:

Python console
>>> from django.db.models.functions import Sign
>>> Vector.objects.create(x=5.4, y=-2.3)
>>> vector = Vector.objects.annotate(x_sign=Sign("x"), y_sign=Sign("y")).get()
>>> vector.x_sign, vector.y_sign
(1, -1)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Sign
>>> FloatField.register_lookup(Sign)
>>> # Get vectors whose signs of components are less than 0.
>>> vectors = Vector.objects.filter(x__sign__lt=0, y__sign__lt=0)

SinLink to this heading

class Sin(expression, **extra)Link to this definition

返回一个数值字段或表达式的正弦值。

用法示例:

Python console
>>> from django.db.models.functions import Sin
>>> Vector.objects.create(x=5.4, y=-2.3)
>>> vector = Vector.objects.annotate(x_sin=Sin("x"), y_sin=Sin("y")).get()
>>> vector.x_sin, vector.y_sin
(-0.7727644875559871, -0.7457052121767203)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Sin
>>> FloatField.register_lookup(Sin)
>>> # Get vectors whose sin() is less than 0
>>> vectors = Vector.objects.filter(x__sin__lt=0, y__sin__lt=0)

SqrtLink to this heading

class Sqrt(expression, **extra)Link to this definition

返回一个非负数值字段或表达式的平方根。

用法示例:

Python console
>>> from django.db.models.functions import Sqrt
>>> Vector.objects.create(x=4.0, y=12.0)
>>> vector = Vector.objects.annotate(x_sqrt=Sqrt("x"), y_sqrt=Sqrt("y")).get()
>>> vector.x_sqrt, vector.y_sqrt
(2.0, 3.46410)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Sqrt
>>> FloatField.register_lookup(Sqrt)
>>> # Get vectors whose sqrt() is less than 5
>>> vectors = Vector.objects.filter(x__sqrt__lt=5, y__sqrt__lt=5)

TanLink to this heading

class Tan(expression, **extra)Link to this definition

返回一个数值字段或表达式的正切值。

用法示例:

Python console
>>> from django.db.models.functions import Tan
>>> Vector.objects.create(x=0, y=12)
>>> vector = Vector.objects.annotate(x_tan=Tan("x"), y_tan=Tan("y")).get()
>>> vector.x_tan, vector.y_tan
(0.0, -0.6358599286615808)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Tan
>>> FloatField.register_lookup(Tan)
>>> # Get vectors whose tangent is less than 0
>>> vectors = Vector.objects.filter(x__tan__lt=0, y__tan__lt=0)

文本函数Link to this heading

ChrLink to this heading

class Chr(expression, **extra)Link to this definition

接受一个数值字段或表达式,并将表达式的文本表示形式作为单个字符返回。它的工作原理与 Python 的 chr() 函数相同。

Length 一样,它也可以在 IntegerField 上作为变换注册。默认的查询名是 chr

用法示例:

Python console
>>> from django.db.models.functions import Chr
>>> Author.objects.create(name="Margaret Smith")
>>> author = Author.objects.filter(name__startswith=Chr(ord("M"))).get()
>>> print(author.name)
Margaret Smith

ConcatLink to this heading

class Concat(*expressions, **extra)Link to this definition

接受至少两个文本字段或表达式的列表,并返回连接后的文本。每个参数必须是文本或字符类型。如果你想把一个 TextField() 和一个 CharField() 连接起来,那么一定要告诉 Django,output_field 应该是一个 TextField()。当连接一个 Value 时,也需要指定一个 output_field,如下面的例子。

这个函数永远不会有一个空的结果。在后端,如果一个空参数导致整个表达式为空,Django 会确保每个空的部分先转换成空字符串。

用法示例:

Python console
>>> # Get the display name as "name (goes_by)"
>>> from django.db.models import CharField, Value as V
>>> from django.db.models.functions import Concat
>>> Author.objects.create(name="Margaret Smith", goes_by="Maggie")
>>> author = Author.objects.annotate(
...     screen_name=Concat("name", V(" ("), "goes_by", V(")"), output_field=CharField())
... ).get()
>>> print(author.screen_name)
Margaret Smith (Maggie)

LeftLink to this heading

class Left(expression, length, **extra)Link to this definition

返回给定文本字段或表达式的第一个 length 字符。

用法示例:

Python console
>>> from django.db.models.functions import Left
>>> Author.objects.create(name="Margaret Smith")
>>> author = Author.objects.annotate(first_initial=Left("name", 1)).get()
>>> print(author.first_initial)
M

LengthLink to this heading

class Length(expression, **extra)Link to this definition

接受单个文本字段或表达式,并返回值的字符数。如果表达式为空,则长度也为空。

用法示例:

Python console
>>> # Get the length of the name and goes_by fields
>>> from django.db.models.functions import Length
>>> Author.objects.create(name="Margaret Smith")
>>> author = Author.objects.annotate(
...     name_length=Length("name"), goes_by_length=Length("goes_by")
... ).get()
>>> print(author.name_length, author.goes_by_length)
(14, None)

它也可以注册为一个转换操作。例如:

Python console
>>> from django.db.models import CharField
>>> from django.db.models.functions import Length
>>> CharField.register_lookup(Length)
>>> # Get authors whose name is longer than 7 characters
>>> authors = Author.objects.filter(name__length__gt=7)

LowerLink to this heading

class Lower(expression, **extra)Link to this definition

接受单个文本字段或表达式,并返回小写表示。

它也可以像 Length 中描述的那样,作为一个变换注册。

用法示例:

Python console
>>> from django.db.models.functions import Lower
>>> Author.objects.create(name="Margaret Smith")
>>> author = Author.objects.annotate(name_lower=Lower("name")).get()
>>> print(author.name_lower)
margaret smith

LPadLink to this heading

class LPad(expression, length, fill_text=Value(' '), **extra)Link to this definition

返回给定的文本字段或表达式的值,在左侧用 fill_text 填充,使结果是 length 字符长。默认的 fill_text 是一个空格。

用法示例:

Python console
>>> from django.db.models import Value
>>> from django.db.models.functions import LPad
>>> Author.objects.create(name="John", alias="j")
>>> Author.objects.update(name=LPad("name", 8, Value("abc")))
1
>>> print(Author.objects.get(alias="j").name)
abcaJohn

LTrimLink to this heading

class LTrim(expression, **extra)Link to this definition

类似于 Trim,但只删除前导空格。

MD5Link to this heading

class MD5(expression, **extra)Link to this definition

接受单个文本字段或表达式,并返回字符串的 MD5 哈希值。

它也可以像 Length 中描述的那样,作为一个变换注册。

用法示例:

Python console
>>> from django.db.models.functions import MD5
>>> Author.objects.create(name="Margaret Smith")
>>> author = Author.objects.annotate(name_md5=MD5("name")).get()
>>> print(author.name_md5)
749fb689816b2db85f5b169c2055b247

OrdLink to this heading

class Ord(expression, **extra)Link to this definition

接受一个文本字段或表达式,并返回该表达式第一个字符的 Unicode 码点值。它的工作原理类似于 Python 的 ord() 函数,但如果表达式超过一个字符,则不会引发异常。

也可以像 Length 中描述的那样,把它注册为一个变换。默认的查找名称是 ord

用法示例:

Python console
>>> from django.db.models.functions import Ord
>>> Author.objects.create(name="Margaret Smith")
>>> author = Author.objects.annotate(name_code_point=Ord("name")).get()
>>> print(author.name_code_point)
77

RepeatLink to this heading

class Repeat(expression, number, **extra)Link to this definition

返回给定文本字段或表达式重复 number 次数的值。

用法示例:

Python console
>>> from django.db.models.functions import Repeat
>>> Author.objects.create(name="John", alias="j")
>>> Author.objects.update(name=Repeat("name", 3))
1
>>> print(Author.objects.get(alias="j").name)
JohnJohnJohn

ReplaceLink to this heading

class Replace(expression, text, replacement=Value(''), **extra)Link to this definition

expression 中用 replacement 替换所有出现的 text。默认替换文本是空字符串。函数的参数是区分大小写的。

用法示例:

Python console
>>> from django.db.models import Value
>>> from django.db.models.functions import Replace
>>> Author.objects.create(name="Margaret Johnson")
>>> Author.objects.create(name="Margaret Smith")
>>> Author.objects.update(name=Replace("name", Value("Margaret"), Value("Margareth")))
2
>>> Author.objects.values("name")
<QuerySet [{'name': 'Margareth Johnson'}, {'name': 'Margareth Smith'}]>

ReverseLink to this heading

class Reverse(expression, **extra)Link to this definition

接受单个文本字段或表达式,并将该表达式的字符按相反顺序返回。

也可以像 Length 中描述的那样,把它注册为一个变换。默认的查询名称是 reverse

用法示例:

Python console
>>> from django.db.models.functions import Reverse
>>> Author.objects.create(name="Margaret Smith")
>>> author = Author.objects.annotate(backward=Reverse("name")).get()
>>> print(author.backward)
htimS teragraM

RPadLink to this heading

class RPad(expression, length, fill_text=Value(' '), **extra)Link to this definition

类似于 LPad,但垫在右边。

RTrimLink to this heading

class RTrim(expression, **extra)Link to this definition

类似于 Trim,但只删除尾部的空格。

SHA1、SHA224`、SHA256`、SHA384` 和 SHA512Link to this heading

class SHA1(expression, **extra)Link to this definition
class SHA224(expression, **extra)Link to this definition
class SHA256(expression, **extra)Link to this definition
class SHA384(expression, **extra)Link to this definition
class SHA512(expression, **extra)Link to this definition

接受单个文本字段或表达式,并返回字符串的特定哈希值。

它们也可以像 Length 中描述的那样注册为变换。

用法示例:

Python console
>>> from django.db.models.functions import SHA1
>>> Author.objects.create(name="Margaret Smith")
>>> author = Author.objects.annotate(name_sha1=SHA1("name")).get()
>>> print(author.name_sha1)
b87efd8a6c991c390be5a68e8a7945a7851c7e5c

StrIndexLink to this heading

class StrIndex(expression, substring, **extra)Link to this definition

Returns a positive integer corresponding to the 1-indexed position of the first occurrence of substring inside expression, or 0 if substring is not found.

用法示例:

Python console
>>> from django.db.models import Value as V
>>> from django.db.models.functions import StrIndex
>>> Author.objects.create(name="Margaret Smith")
>>> Author.objects.create(name="Smith, Margaret")
>>> Author.objects.create(name="Margaret Jackson")
>>> Author.objects.filter(name="Margaret Jackson").annotate(
...     smith_index=StrIndex("name", V("Smith"))
... ).get().smith_index
0
>>> authors = Author.objects.annotate(smith_index=StrIndex("name", V("Smith"))).filter(
...     smith_index__gt=0
... )
<QuerySet [<Author: Margaret Smith>, <Author: Smith, Margaret>]>

SubstrLink to this heading

class Substr(expression, pos, length=None, **extra)Link to this definition

从字段或表达式的位置 pos 开始返回一个长度为 length 的子串。如果 lengthNone,那么将返回字符串的其余部分。

用法示例:

Python console
>>> # Set the alias to the first 5 characters of the name as lowercase
>>> from django.db.models.functions import Lower, Substr
>>> Author.objects.create(name="Margaret Smith")
>>> Author.objects.update(alias=Lower(Substr("name", 1, 5)))
1
>>> print(Author.objects.get(name="Margaret Smith").alias)
marga

TrimLink to this heading

class Trim(expression, **extra)Link to this definition

返回给定的文本字段或表达式的值,并去除前导和尾部的空格。

用法示例:

Python console
>>> from django.db.models.functions import Trim
>>> Author.objects.create(name="  John  ", alias="j")
>>> Author.objects.update(name=Trim("name"))
1
>>> print(Author.objects.get(alias="j").name)
John

UpperLink to this heading

class Upper(expression, **extra)Link to this definition

接受单个文本字段或表达式,并返回大写表示。

它也可以像 Length 中描述的那样,作为一个变换注册。

用法示例:

Python console
>>> from django.db.models.functions import Upper
>>> Author.objects.create(name="Margaret Smith")
>>> author = Author.objects.annotate(name_upper=Upper("name")).get()
>>> print(author.name_upper)
MARGARET SMITH

UUID functionsLink to this heading

UUID4Link to this heading

class UUID4Link to this definition

Generates a version 4 UUID, which is random and is generated using a cryptographically secure method.

UUID7Link to this heading

class UUID7(shift=None)Link to this definition

Generates a version 7 UUID, which starts with a time-based component.

窗口函数Link to this heading

Window 表达式中,有很多函数可以用来计算元素的等级或某些行的 Ntile

CumeDistLink to this heading

class CumeDist(*expressions, **extra)Link to this definition

计算一个窗口或分区内的数值的累积分布。累计分布被定义为当前行之前的行数或同行行数除以框架中的总行数。

DenseRankLink to this heading

class DenseRank(*expressions, **extra)Link to this definition

相当于 Rank,但没有间隙。

FirstValueLink to this heading

class FirstValue(expression, **extra)Link to this definition

返回窗口帧第一行的值,如果没有这个值,则返回 None

LagLink to this heading

class Lag(expression, offset=1, default=None, **extra)Link to this definition

计算 offset 的偏移值,如果没有行存在,返回 default

default 必须与 expression 具有相同的类型,但是,这只由数据库验证,而不是在 Python 中验证。

LastValueLink to this heading

class LastValue(expression, **extra)Link to this definition

类似于 FirstValue,它计算给定框架子句中的最后一个值。

LeadLink to this heading

class Lead(expression, offset=1, default=None, **extra)Link to this definition

计算给定 frame 中的前导值。offsetdefault 都是根据当前行的情况来计算的。

default 必须与 expression 具有相同的类型,但是,这只由数据库验证,而不是在 Python 中验证。

NthValueLink to this heading

class NthValue(expression, nth=1, **extra)Link to this definition

计算相对于窗口内偏移量 nth (必须是正值)的行。如果没有行,返回 None

一些数据库可能会以不同的方式处理不存在的 nth-value,例如,对于基于字符的表达式,Oracle 会返回一个空字符串,而不是 None。在这些情况下,Django 不做任何转换。

NtileLink to this heading

class Ntile(num_buckets=1, **extra)Link to this definition

为帧子句中的每一行计算一个分区,在 1 和 num_buckets 之间尽可能均匀地分配数字。如果行没有被平均分配到若干个桶中,则一个或多个桶将被更频繁地表示。

PercentRankLink to this heading

class PercentRank(*expressions, **extra)Link to this definition

计算帧子句中行的相对排名。这个计算等同于评估:

Text
(rank - 1) / (total rows - 1)

下表解释了行的相对排名计算:

行 #

排名

计算

相对排名

1

15

1

(1-1)/(7-1)

0.0000

2

20

2

(2-1)/(7-1)

0.1666

3

20

2

(2-1)/(7-1)

0.1666

4

20

2

(2-1)/(7-1)

0.1666

5

30

5

(5-1)/(7-1)

0.6666

6

30

5

(5-1)/(7-1)

0.6666

7

40

7

(7-1)/(7-1)

1.0000

RankLink to this heading

class Rank(*expressions, **extra)Link to this definition

RowNumber 类似,该函数对窗口中的行进行排序。计算出的排名包含有空隙。使用 DenseRank 来计算没有空隙的排名。

RowNumberLink to this heading

class RowNumber(*expressions, **extra)Link to this definition

如果没有对 窗口帧 进行分区,则根据帧子句的顺序或整个查询的顺序计算行数。