Django数据库函数使用

Django数据库函数使用

通用方法

from django.db.models.functions import Cast, Coalesce, Concat, ConcatPair, Greatest

# Cast,类型转换
q1 = TradeDetail.objects.values("profit", "name").annotate( profit=F("money") * F(Cast('direction', FloatField())))

# Coalesce,从前向后,查询第一个不为空的值
q2 = TradeDetail.objects.annotate(c=Coalesce('name', 'money'))

# Concat拼接
TradeDetail.objects.update(name=Concat('name', 'money'))

# ConcatPair,拼接(仅两个参数)
qs = UserInfo.objects.annotate(new_name=ConcatPair('name', 'addr', 'school'))
for i in qs:  # addr是-  school是*
  print(i.new_name)  # lqz-*

# Greatest, 获取比较大的值; least获取比较小的值
TradeDetail.objects.annotate(c=Greatest('id', 'money',output_field=FloatField()))

# Length获取长度
qs = UserInfo.objects.annotate(new=Length('name')).values('new')
# {'new': 3}

# Lower,Upper,变大小写
TradeDetail.objects.annotate(c=Lower('name'))
TradeDetail.objects.annotate(c=Upper('name'))

# Now。获取当前时间
TradeDetail.objects.annotate(c=Now())

# Left 获取字段的指定字符长度的值
qs = UserInfo.objects.annotate(new_name=Left('name', 2)).values('new_name')
# {'new_name': 'lq'}

Extract

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

取一个代表 DateFieldDateTimeFieldTimeFieldDurationFieldlookup_nameexpression 和一个 lookup_name 引用的日期部分作为 IntegerField 返回。Django 通常使用数据库的 extract 函数,所以你可以使用任何数据库支持的 lookup_nametzinfo 子类,通常由 pytz 提供,可以通过提取特定时区的值。

给定日期时间 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
qs = UserInfo.objects.annotate(
  year=Extract('registered_on', 'year'),
  month=Extract('registered_on', 'month'),
  day=Extract('registered_on', 'day'),
  quarter=Extract('registered_on', 'quarter'),
  week=Extract('registered_on', 'week'),
  week_day=Extract('registered_on', 'week_day'),
  iso_week_day=Extract('registered_on', 'iso_week_day'),
).values('year', 'month', 'day', 'quarter', 'week', 'week_day', 'iso_week_day')
for i in qs:
  print(i)
  
{'year': 2023, 'month': 1, 'day': 2, 'quarter': 1, 'week': 1, 'week_day': 2, 'iso_week_day': 1}
{'year': 2023, 'month': 1, 'day': 11, 'quarter': 1, 'week': 2, 'week_day': 4, 'iso_week_day': 3}
{'year': 2021, 'month': 7, 'day': 12, 'quarter': 3, 'week': 28, 'week_day': 2, 'iso_week_day': 1}
{'year': 2022, 'month': 1, 'day': 2, 'quarter': 1, 'week': 52, 'week_day': 1, 'iso_week_day': 7}
{'year': 2023, 'month': 1, 'day': 9, 'quarter': 1, 'week': 2, 'week_day': 2, 'iso_week_day': 1}
{'year': 2020, 'month': 1, 'day': 1, 'quarter': 1, 'week': 1, 'week_day': 4, 'iso_week_day': 3}
{'year': 2022, 'month': 12, 'day': 7, 'quarter': 4, 'week': 49, 'week_day': 4, 'iso_week_day': 3}

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

Trunc

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

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

给定日期时间 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+10:00
  • "month": 2015-06-01 00:00:00+10:00
  • "week": 2015-06-16 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

年的偏移量为 +11:00,因为结果过渡到夏令时。

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

qs = UserInfo.objects.annotate(
  init_year=Trunc('registered_on', 'year'),
  init_month=Trunc('registered_on', 'month'),
  init_day=Trunc('registered_on', 'day'),
  init_quarter=Trunc('registered_on', 'quarter'),
  init_week=Trunc('registered_on', 'week'),

).values('init_year', 'init_month', 'init_day', 'init_quarter', 'init_week')
for i in qs:
  print(i)

{'init_year': datetime.date(2023, 1, 1), 'init_month': datetime.date(2023, 1, 1), 'init_day': datetime.date(2023, 1, 2), 'init_quarter': datetime.date(2023, 1, 1), 'init_week': datetime.date(2023, 1, 2)}
{'init_year': datetime.date(2023, 1, 1), 'init_month': datetime.date(2023, 1, 1), 'init_day': datetime.date(2023, 1, 11), 'init_quarter': datetime.date(2023, 1, 1), 'init_week': datetime.date(2023, 1, 9)}
{'init_year': datetime.date(2021, 1, 1), 'init_month': datetime.date(2021, 7, 1), 'init_day': datetime.date(2021, 7, 12), 'init_quarter': datetime.date(2021, 7, 1), 'init_week': datetime.date(2021, 7, 12)}
{'init_year': datetime.date(2022, 1, 1), 'init_month': datetime.date(2022, 1, 1), 'init_day': datetime.date(2022, 1, 2), 'init_quarter': datetime.date(2022, 1, 1), 'init_week': datetime.date(2021, 12, 27)}
{'init_year': datetime.date(2023, 1, 1), 'init_month': datetime.date(2023, 1, 1), 'init_day': datetime.date(2023, 1, 9), 'init_quarter': datetime.date(2023, 1, 1), 'init_week': datetime.date(2023, 1, 9)}
{'init_year': datetime.date(2020, 1, 1), 'init_month': datetime.date(2020, 1, 1), 'init_day': datetime.date(2020, 1, 1), 'init_quarter': datetime.date(2020, 1, 1), 'init_week': datetime.date(2019, 12, 30)}
{'init_year': datetime.date(2022, 1, 1), 'init_month': datetime.date(2022, 12, 1), 'init_day': datetime.date(2022, 12, 7), 'init_quarter': datetime.date(2022, 10, 1), 'init_week': datetime.date(2022, 12, 5)}
posted @ 2023-01-31 15:06  zong涵  阅读(80)  评论(0编辑  收藏  举报