データベース関数—Djangoドキュメント

提供:Dev Guides
< DjangoDjango/docs/3.2.x/ref/models/database-functions
移動先:案内検索

データベース機能

以下に記載されているクラスは、ユーザーが基盤となるデータベースによって提供される関数をDjangoの注釈、集計、またはフィルターとして使用する方法を提供します。 関数もであるため、集計関数などの他の式と組み合わせて使用できます。

各関数の例では、次のモデルを使用します。

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)

通常、CharFieldnull=Trueを許可することはお勧めしません。これにより、フィールドに2つの「空の値」を含めることができますが、以下のCoalesceの例では重要です。

比較および変換関数

Cast

class Cast(expression, output_field)

expressionの結果タイプをoutput_fieldの結果タイプに強制します。

使用例:

>>> 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

Coalesce

class Coalesce(*expressions, **extra)

少なくとも2つのフィールド名または式のリストを受け入れ、最初のnull以外の値を返します(空の文字列はnull値とは見なされないことに注意してください)。 各引数は同様のタイプである必要があるため、テキストと数字を混在させるとデータベースエラーが発生します。

使用例:

>>> # Get a screen name from least to most public
>>> from django.db.models import Sum, Value as V
>>> 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
>>> aggregated = Author.objects.aggregate(
...    combined_age=Coalesce(Sum('age'), V(0)),
...    combined_age_default=Sum('age'))
>>> print(aggregated['combined_age'])
0
>>> print(aggregated['combined_age_default'])
None

警告

MySQLでCoalesceに渡されたPython値は、正しいデータベースタイプに明示的にキャストされない限り、誤ったタイプに変換される可能性があります。

>>> from django.db.models import DateTimeField
>>> from django.db.models.functions import Cast, Coalesce
>>> from django.utils import timezone
>>> now = timezone.now()
>>> Coalesce('updated', Cast(now, DateTimeField()))

Collate

class Collate(expression, collation)

バージョン3.2の新機能。


クエリの対象となる式と照合名を受け取ります。

たとえば、SQLiteで大文字と小文字を区別せずにフィルタリングするには:

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

PostgreSQLなどで注文するときにも使用できます。

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

Greatest

class Greatest(*expressions, **extra)

少なくとも2つのフィールド名または式のリストを受け入れ、最大値を返します。 各引数は同様のタイプである必要があるため、テキストと数字を混在させるとデータベースエラーが発生します。

使用例:

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)

>>> 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の最新のものになります。

警告

1つ以上の式がnullである場合のGreatestの動作は、データベースによって異なります。

  • PostgreSQL:Greatestは最大の非ヌル式を返します。すべての式がnullの場合はnullを返します。
  • SQLite、Oracle、およびMySQL:いずれかの式がnullの場合、Greatestnullを返します。

デフォルトとして提供する適切な最小値がわかっている場合は、Coalesceを使用してPostgreSQLの動作をエミュレートできます。


JSONObject

class JSONObject(**fields)

バージョン3.2の新機能。


キーと値のペアのリストを取得し、それらのペアを含むJSONオブジェクトを返します。

使用例:

>>> 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}

Least

class Least(*expressions, **extra)

少なくとも2つのフィールド名または式のリストを受け入れ、最小値を返します。 各引数は同様のタイプである必要があるため、テキストと数字を混在させるとデータベースエラーが発生します。

警告

1つ以上の式がnullである場合のLeastの動作は、データベースによって異なります。

  • PostgreSQL:Leastは、null以外の最小の式を返します。すべての式がnullの場合は、nullを返します。
  • SQLite、Oracle、およびMySQL:いずれかの式がnullの場合、Leastnullを返します。

デフォルトとして提供する適切な最大値がわかっている場合は、Coalesceを使用してPostgreSQLの動作をエミュレートできます。


NullIf

class NullIf(expression1, expression2)

2つの式を受け入れ、等しい場合はNoneを返し、そうでない場合はexpression1を返します。

Oracleに関する警告

Oracle規則により、式が CharField 型の場合、この関数はNoneではなく空の文字列を返します。

OracleではNULLを最初の引数として受け入れないため、Value(None)expression1に渡すことは禁止されています。


日付関数

各関数の例では、次のモデルを使用します。

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)

Extract

class Extract(expression, lookup_name=None, tzinfo=None, **extra)

日付のコンポーネントを数値として抽出します。

DateFieldDateTimeFieldTimeField、またはDurationFieldを表すexpressionlookup_nameを受け取り、 lookup_nameによってIntegerFieldとして参照される日付の一部。 Djangoは通常、データベースの抽出機能を使用するため、データベースがサポートするlookup_nameを使用できます。 tzinfoサブクラス(通常はpytzによって提供されます)を渡して、特定のタイムゾーンの値を抽出できます。

日時2015-06-15 23:30:01.000321+00:00を指定すると、組み込みのlookup_nameは次を返します。

  • 「年」:2015
  • 「iso_year」:2015
  • 「四半期」:2
  • 「月」:6
  • 「日」:15
  • 「週」:25
  • 「week_day」:2
  • 「iso_week_day」:1
  • 「時間」:23
  • 「分」:30
  • 「秒」:1

Australia/Melbourneのような別のタイムゾーンがDjangoでアクティブになっている場合、値が抽出される前に日時がタイムゾーンに変換されます。 上記の例の日付におけるメルボルンのタイムゾーンオフセットは+10:00です。 このタイムゾーンがアクティブなときに返される値は、次の点を除いて上記と同じです。

  • 「日」:16
  • 「week_day」:3
  • 「iso_week_day」:2
  • 「時間」:9

week_day

week_day lookup_typeは、ほとんどのデータベースおよびPythonの標準関数とは異なる方法で計算されます。 この関数は、日曜日に1、月曜日に2、土曜日に7を返します。

Pythonでの同等の計算は次のとおりです。

>>> from datetime import datetime
>>> dt = datetime(2015, 6, 15)
>>> (dt.isoweekday() % 7) + 1
2

week

week lookup_typeは、 ISO-8601 に基づいて計算されます。つまり、週は月曜日から始まります。 年の最初の週は、その年の最初の木曜日を含む週です。 最初の週には、その年の日の大部分(4つ以上)があります。 返される値は、1から52または53の範囲です。


上記の各lookup_nameには、対応するExtractサブクラス(以下にリスト)があり、より冗長な同等物の代わりに通常使用する必要があります。 Extract(..., lookup_name='year')ではなくExtractYear(...)を使用してください。

使用例:

>>> 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抽出

class ExtractYear(expression, tzinfo=None, **extra)
;; lookup_name = 'year'
class ExtractIsoYear(expression, tzinfo=None, **extra)
ISO-8601の週番号の年を返します。
lookup_name = 'iso_year'
class ExtractMonth(expression, tzinfo=None, **extra)
;; lookup_name = 'month'
class ExtractDay(expression, tzinfo=None, **extra)
;; lookup_name = 'day'
class ExtractWeekDay(expression, tzinfo=None, **extra)
;; lookup_name = 'week_day'
class ExtractIsoWeekDay(expression, tzinfo=None, **extra)

バージョン3.1の新機能。

ISO-8601の平日を返します。1日目は月曜日、7日目は日曜日です。

lookup_name = 'iso_week_day'
class ExtractWeek(expression, tzinfo=None, **extra)
;; lookup_name = 'week'
class ExtractQuarter(expression, tzinfo=None, **extra)
;; lookup_name = 'quarter'

これらは論理的にExtract('date_field', lookup_name)と同等です。 各クラスは、DateFieldおよびDateTimeField__(lookup_name)として登録されているTransformでもあります。 __year

DateFieldには時間コンポーネントがないため、DateFieldで使用できるのは日付部分を処理するExtractサブクラスのみです。

>>> from datetime import datetime
>>> from django.utils import timezone
>>> from django.db.models.functions import (
...     ExtractDay, ExtractMonth, ExtractQuarter, ExtractWeek,
...     ExtractIsoWeekDay, ExtractWeekDay, ExtractIsoYear, ExtractYear,
... )
>>> start_2015 = datetime(2015, 6, 15, 23, 30, 1, tzinfo=timezone.utc)
>>> end_2015 = datetime(2015, 6, 16, 13, 11, 27, tzinfo=timezone.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抽出

以下に加えて、上記のDateFieldのすべての抽出物は、DateTimeFieldでも使用できます。

class ExtractHour(expression, tzinfo=None, **extra)
;; lookup_name = 'hour'
class ExtractMinute(expression, tzinfo=None, **extra)
;; lookup_name = 'minute'
class ExtractSecond(expression, tzinfo=None, **extra)
;; lookup_name = 'second'

これらは論理的にExtract('datetime_field', lookup_name)と同等です。 各クラスは、DateTimeField__(lookup_name)として登録されているTransformでもあります。 __minute

DateTimeFieldの例:

>>> from datetime import datetime
>>> from django.utils import timezone
>>> 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=timezone.utc)
>>> end_2015 = datetime(2015, 6, 16, 13, 11, 27, tzinfo=timezone.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}

:setting: `USE_TZ`Trueの場合、日時はUTCでデータベースに保存されます。 Djangoで別のタイムゾーンがアクティブになっている場合、値が抽出される前に日時がそのタイムゾーンに変換されます。 以下の例は、メルボルンのタイムゾーン(UTC +10:00)に変換されます。これにより、返される日、平日、および時間の値が変更されます。

>>> import pytz
>>> melb = pytz.timezone('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関数に明示的に渡すと同じように動作し、アクティブなタイムゾーンよりも優先されます。

>>> import pytz
>>> melb = pytz.timezone('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}

Now

class Now

通常はSQL CURRENT_TIMESTAMPを使用して、クエリが実行されたときのデータベースサーバーの現在の日付と時刻を返します。

使用例:

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

PostgreSQLに関する考慮事項

PostgreSQLでは、SQL CURRENT_TIMESTAMPは現在のトランザクションが開始された時刻を返します。 したがって、データベース間の互換性のために、Now()は代わりにSTATEMENT_TIMESTAMPを使用します。 トランザクションのタイムスタンプが必要な場合は、 django.contrib.postgres.functions.TransactionNow を使用してください。


Trunc

class Trunc(expression, kind, output_field=None, tzinfo=None, is_dst=None, **extra)

重要なコンポーネントまで日付を切り捨てます。

特定の年、時間、または日に何かが発生したかどうかだけを気にし、正確な秒は気にしない場合は、Trunc(およびそのサブクラス)がデータのフィルタリングまたは集計に役立ちます。 たとえば、Truncを使用して、1日あたりの販売数を計算できます。

Truncは、DateFieldTimeField、またはDateTimeField、日付を表すkindを表す単一のexpressionを取りますまたは時間部分、およびDateTimeField()TimeField()、またはDateField()のいずれかであるoutput_fieldoutput_fieldに応じて日時、日付、または時刻を返し、kindまでのフィールドを最小値に設定します。 output_fieldを省略すると、デフォルトでexpressionoutput_fieldになります。 tzinfoサブクラス(通常はpytzによって提供されます)を渡して、特定のタイムゾーンの値を切り捨てることができます。

is_dstパラメーターは、pytzが夏時間の存在しないあいまいな日時を解釈する必要があるかどうかを示します。 デフォルト(is_dst=Noneの場合)では、pytzはそのような日時の例外を発生させます。

日時2015-06-15 14:30:50.000321+00:00を指定すると、組み込みのkindは次を返します。

  • 「年」:2015-01-01 0000:00 + 00:00
  • 「四半期」:2015-04-01 0000:00 + 00:00
  • 「月」:2015-06-01 00:00:00 + 00:00
  • 「週」:2015-06-15 00:00:00 + 00:00
  • 「日」:2015-06-15 00:00:00 + 00:00
  • 「時間」:2015-06-15 14:00:00 + 00:00
  • 「分」:2015-06-15 14:30:00 + 00:00
  • 「2番目」:2015-06-15 14:30:50 + 00:00

Australia/Melbourneなどの別のタイムゾーンがDjangoでアクティブになっている場合、値が切り捨てられる前に、日時が新しいタイムゾーンに変換されます。 上記の例の日付におけるメルボルンのタイムゾーンオフセットは+10:00です。 このタイムゾーンがアクティブなときに返される値は次のとおりです。

  • 「年」:2015-01-01 00:00:00 + 11:00
  • 「四半期」:2015-04-01 00:00:00 + 10:00
  • 「月」:2015-06-01 00:00:00 + 10:00
  • 「週」:2015-06-16 00:00:00 + 10:00
  • 「日」:2015-06-16 00:00:00 + 10:00
  • 「時間」:2015-06-16 00:00:00 + 10:00
  • 「分」:2015-06-16 00:30:00 + 10:00
  • 「2番目」:2015-06-16 00:30:50 + 10:00

結果が夏時間に移行したため、年のオフセットは+11:00になります。

上記の各kindには、対応するTruncサブクラス(以下にリスト)があり、より冗長な同等物の代わりに通常使用する必要があります。 Trunc(..., kind='year')ではなくTruncYear(...)を使用してください。

サブクラスはすべてトランスフォームとして定義されていますが、ルックアップ名はExtractサブクラスによってすでに予約されているため、フィールドには登録されていません。

使用例:

>>> 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切り捨て

class TruncYear(expression, output_field=None, tzinfo=None, is_dst=None, **extra)
;; kind = 'year'
class TruncMonth(expression, output_field=None, tzinfo=None, is_dst=None, **extra)
;; kind = 'month'
class TruncWeek(expression, output_field=None, tzinfo=None, is_dst=None, **extra)
週の月曜日の深夜に切り捨てられます。
kind = 'week'
class TruncQuarter(expression, output_field=None, tzinfo=None, is_dst=None, **extra)
;; kind = 'quarter'

これらは論理的にTrunc('date_field', kind)と同等です。 kindまでの日付のすべての部分が切り捨てられるため、精度の低い日付のグループ化またはフィルタリングが可能になります。 expressionは、DateFieldまたはDateTimeFieldのいずれかのoutput_fieldを持つことができます。

DateFieldには時間コンポーネントがないため、DateFieldで使用できるのは日付部分を処理するTruncサブクラスのみです。

>>> from datetime import datetime
>>> from django.db.models import Count
>>> from django.db.models.functions import TruncMonth, TruncYear
>>> from django.utils import timezone
>>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=timezone.utc)
>>> start2 = datetime(2015, 6, 15, 14, 40, 2, 123, tzinfo=timezone.utc)
>>> start3 = datetime(2015, 12, 31, 17, 5, 27, 999, tzinfo=timezone.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 pytz
>>> melb = pytz.timezone('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切り捨て

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

バージョン3.2で変更: tzinfoパラメーターが追加されました。

TruncDateは、組み込みのSQL切り捨て関数を使用するのではなく、expressionを日付にキャストします。 また、DateTimeFieldのトランスフォームとして__dateとして登録されています。

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

バージョン3.2で変更: tzinfoパラメーターが追加されました。

TruncTimeは、組み込みのSQL切り捨て関数を使用するのではなく、expressionを時間にキャストします。 また、DateTimeFieldのトランスフォームとして__timeとして登録されています。

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

これらは論理的にTrunc('datetime_field', kind)と同等です。 kindまでの日付のすべての部分が切り捨てられ、より低い精度で日時をグループ化またはフィルタリングできます。 expressionには、DateTimeFieldoutput_fieldが必要です。

使用例:

>>> from datetime import date, datetime
>>> from django.db.models import Count
>>> from django.db.models.functions import (
...     TruncDate, TruncDay, TruncHour, TruncMinute, TruncSecond,
... )
>>> from django.utils import timezone
>>> import pytz
>>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=timezone.utc)
>>> Experiment.objects.create(start_datetime=start1, start_date=start1.date())
>>> melb = pytz.timezone('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=<DstTzInfo 'Australia/Melbourne' AEST+10:00:00 STD>),
 'hour': datetime.datetime(2014, 6, 16, 0, 0, tzinfo=<DstTzInfo 'Australia/Melbourne' AEST+10:00:00 STD>),
 'minute': 'minute': datetime.datetime(2014, 6, 15, 14, 30, tzinfo=<UTC>),
 'second': datetime.datetime(2014, 6, 15, 14, 30, 50, tzinfo=<UTC>)
}

TimeField切り捨て

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

これらは論理的にTrunc('time_field', kind)と同等です。 kindまでの時間のすべての部分が切り捨てられるため、精度の低い時間のグループ化またはフィルタリングが可能になります。 expressionは、TimeFieldまたはDateTimeFieldのいずれかのoutput_fieldを持つことができます。

TimeFieldには日付コンポーネントがないため、TimeFieldで使用できるのは時間部分を処理するTruncサブクラスのみです。

>>> from datetime import datetime
>>> from django.db.models import Count, TimeField
>>> from django.db.models.functions import TruncHour
>>> from django.utils import timezone
>>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=timezone.utc)
>>> start2 = datetime(2014, 6, 15, 14, 40, 2, 123, tzinfo=timezone.utc)
>>> start3 = datetime(2015, 12, 31, 17, 5, 27, 999, tzinfo=timezone.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 pytz
>>> melb = pytz.timezone('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

数学関数

数学関数の例では、次のモデルを使用します。

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

Abs

class Abs(expression, **extra)

数値フィールドまたは式の絶対値を返します。

使用例:

>>> 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)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

ACos

class ACos(expression, **extra)

数値フィールドまたは式の逆余弦を返します。 式の値は、-1から1の範囲内である必要があります。

使用例:

>>> 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)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

ASin

class ASin(expression, **extra)

数値フィールドまたは式のアークサインを返します。 式の値は-1から1の範囲でなければなりません。

使用例:

>>> 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)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

ATan

class ATan(expression, **extra)

数値フィールドまたは式のアークタンジェントを返します。

使用例:

>>> 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)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

ATan2

class ATan2(expression1, expression2, **extra)

expression1 / expression2のアークタンジェントを返します。

使用例:

>>> 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

Ceil

class Ceil(expression, **extra)

数値フィールドまたは式以上の最小の整数を返します。

使用例:

>>> 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)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

Cos

class Cos(expression, **extra)

数値フィールドまたは式のコサインを返します。

使用例:

>>> 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)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

Cot

class Cot(expression, **extra)

数値フィールドまたは式のコタンジェントを返します。

使用例:

>>> 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)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

Degrees

class Degrees(expression, **extra)

数値フィールドまたは式をラジアンから度に変換します。

使用例:

>>> 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)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

Exp

class Exp(expression, **extra)

e(自然対数の底)の値を数値フィールドまたは式の累乗で返します。

使用例:

>>> 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)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

Floor

class Floor(expression, **extra)

数値フィールドまたは式以下の最大の整数値を返します。

使用例:

>>> 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)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

Ln

class Ln(expression, **extra)

自然対数を数値フィールドまたは式で返します。

使用例:

>>> 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)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

Log

class Log(expression1, expression2, **extra)

2つの数値フィールドまたは式を受け入れ、最初の対数を2番目の底に返します。

使用例:

>>> 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

Mod

class Mod(expression1, expression2, **extra)

2つの数値フィールドまたは式を受け入れ、最初の余りを2番目で割った値を返します(モジュロ演算)。

使用例:

>>> 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

Pi

class Pi(**extra)

数学定数πの値を返します。


Power

class Power(expression1, expression2, **extra)

2つの数値フィールドまたは式を受け入れ、最初の値を2番目の累乗で返します。

使用例:

>>> 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

Radians

class Radians(expression, **extra)

数値フィールドまたは式を度からラジアンに変換します。

使用例:

>>> 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)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

Random

class Random(**extra)

バージョン3.2の新機能。


0.0 ≤ x < 1.0の範囲のランダムな値を返します。


Round

class Round(expression, **extra)

数値フィールドまたは式を最も近い整数に丸めます。 半分の値が切り上げられるか切り下げられるかは、データベースによって異なります。

使用例:

>>> from django.db.models.functions import Round
>>> Vector.objects.create(x=5.4, y=-2.3)
>>> vector = Vector.objects.annotate(x_r=Round('x'), y_r=Round('y')).get()
>>> vector.x_r, vector.y_r
(5.0, -2.0)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

Sign

class Sign(expression, **extra)

数値フィールドまたは式の符号(-1、0、1)を返します。

使用例:

>>> 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)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

Sin

class Sin(expression, **extra)

数値フィールドまたは式のサインを返します。

使用例:

>>> 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)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

Sqrt

class Sqrt(expression, **extra)

非負の数値フィールドまたは式の平方根を返します。

使用例:

>>> 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)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

Tan

class Tan(expression, **extra)

数値フィールドまたは式の接線を返します。

使用例:

>>> 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)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

テキスト関数

Chr

class Chr(expression, **extra)

数値フィールドまたは式を受け入れ、式のテキスト表現を単一の文字として返します。 Pythonのchr()関数と同じように機能します。

Length と同様に、IntegerFieldでトランスフォームとして登録できます。 デフォルトのルックアップ名はchrです。

使用例:

>>> 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

Concat

class Concat(*expressions, **extra)

少なくとも2つのテキストフィールドまたは式のリストを受け入れ、連結されたテキストを返します。 各引数は、テキスト型または文字型である必要があります。 TextField()CharField()と連結する場合は、output_fieldTextField()にする必要があることをDjangoに必ず伝えてください。 以下の例のようにValueを連結する場合も、output_fieldを指定する必要があります。

この関数の結果がnullになることはありません。 null引数によって式全体がnullになるバックエンドでは、Djangoは各null部分が最初に空の文字列に変換されることを保証します。

使用例:

>>> # 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)

Left

class Left(expression, length, **extra)

指定されたテキストフィールドまたは式の最初のlength文字を返します。

使用例:

>>> 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

Length

class Length(expression, **extra)

単一のテキストフィールドまたは式を受け入れ、値の文字数を返します。 式がnullの場合、長さもnullになります。

使用例:

>>> # 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)

トランスフォームとして登録することもできます。 例えば:

>>> 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)

Lower

class Lower(expression, **extra)

単一のテキストフィールドまたは式を受け入れ、小文字の表現を返します。

Length で説明されているように、トランスフォームとして登録することもできます。

使用例:

>>> 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

LPad

class LPad(expression, length, fill_text=Value(' '), **extra)

結果の値がlength文字の長さになるように、左側にfill_textが埋め込まれた指定されたテキストフィールドまたは式の値を返します。 デフォルトのfill_textはスペースです。

使用例:

>>> 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

LTrim

class LTrim(expression, **extra)

Trim に似ていますが、先頭のスペースのみを削除します。


MD5

class MD5(expression, **extra)

単一のテキストフィールドまたは式を受け入れ、文字列のMD5ハッシュを返します。

Length で説明されているように、トランスフォームとして登録することもできます。

使用例:

>>> 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

Ord

class Ord(expression, **extra)

単一のテキストフィールドまたは式を受け入れ、その式の最初の文字のUnicodeコードポイント値を返します。 Pythonのord()関数と同様に機能しますが、式が複数文字の長さの場合、例外は発生しません。

Length で説明されているように、トランスフォームとして登録することもできます。 デフォルトのルックアップ名はordです。

使用例:

>>> 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

Repeat

class Repeat(expression, number, **extra)

number回繰り返された指定されたテキストフィールドまたは式の値を返します。

使用例:

>>> 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

Replace

class Replace(expression, text, replacement=Value(), **extra)

expression内のtextのすべての出現箇所をreplacementに置き換えます。 デフォルトの置換テキストは空の文字列です。 関数の引数では大文字と小文字が区別されます。

使用例:

>>> 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'}]>

Reverse

class Reverse(expression, **extra)

単一のテキストフィールドまたは式を受け入れ、その式の文字を逆の順序で返します。

Length で説明されているように、トランスフォームとして登録することもできます。 デフォルトのルックアップ名はreverseです。

使用例:

>>> 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

RPad

class RPad(expression, length, fill_text=Value(' '), **extra)

LPad に似ていますが、右側にパッドがあります。


RTrim

class RTrim(expression, **extra)

Trim に似ていますが、末尾のスペースのみを削除します。


SHA1、SHA224、SHA256、SHA384、およびSHA512

class SHA1(expression, **extra)
class SHA224(expression, **extra)
class SHA256(expression, **extra)
class SHA384(expression, **extra)
class SHA512(expression, **extra)

単一のテキストフィールドまたは式を受け入れ、文字列の特定のハッシュを返します。

Length で説明されているように、トランスフォームとして登録することもできます。

使用例:

>>> 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

PostgreSQL

pgcrypto拡張機能をインストールする必要があります。 CryptoExtension 移行操作を使用してインストールできます。


オラクル

OracleはSHA224関数をサポートしていません。


StrIndex

class StrIndex(string, substring, **extra)

string内で最初に出現するsubstringの1インデックス位置に対応する正の整数を返します。substringが見つからない場合は0を返します。

使用例:

>>> 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>]>

警告

MySQLでは、データベーステーブルの照合によって、文字列の比較(この関数のexpressionsubstringなど)で大文字と小文字が区別されるかどうかが決まります。 デフォルトでは、比較では大文字と小文字は区別されません。


Substr

class Substr(expression, pos, length=None, **extra)

位置posで始まるフィールドまたは式から長さlengthの部分文字列を返します。 位置は1インデックスであるため、位置は0より大きくなければなりません。 lengthNoneの場合、残りの文字列が返されます。

使用例:

>>> # 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

Trim

class Trim(expression, **extra)

前後のスペースを削除して、指定されたテキストフィールドまたは式の値を返します。

使用例:

>>> 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

Upper

class Upper(expression, **extra)

単一のテキストフィールドまたは式を受け入れ、大文字の表現を返します。

Length で説明されているように、トランスフォームとして登録することもできます。

使用例:

>>> 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

ウィンドウ関数

Window 式で、要素のランクまたは一部の行の Ntile を計算するために使用する関数がいくつかあります。

CumeDist

class CumeDist(*expressions, **extra)

ウィンドウまたはパーティション内の値の累積分布を計算します。 累積分布は、現在の行の前またはピアリングされている行の数をフレーム内の行の総数で割ったものとして定義されます。


DenseRank

class DenseRank(*expressions, **extra)

ランクと同等ですが、ギャップはありません。


FirstValue

class FirstValue(expression, **extra)

ウィンドウフレームの最初の行である行で評価された値を返します。そのような値が存在しない場合はNoneを返します。


Lag

class Lag(expression, offset=1, default=None, **extra)

offsetによってオフセットされた値を計算し、そこに行が存在しない場合は、defaultを返します。

defaultexpressionと同じタイプである必要がありますが、これはデータベースによってのみ検証され、Pythonでは検証されません。

MariaDBとdefault

MariaDB defaultパラメーターをサポートしていません。


LastValue

class LastValue(expression, **extra)

FirstValue と比較して、指定されたフレーム句の最後の値を計算します。


Lead

class Lead(expression, offset=1, default=None, **extra)

指定されたフレームの先行値を計算します。 offsetdefaultの両方が、現在の行に関して評価されます。

defaultexpressionと同じタイプである必要がありますが、これはデータベースによってのみ検証され、Pythonでは検証されません。

MariaDBとdefault

MariaDB defaultパラメーターをサポートしていません。


NthValue

class NthValue(expression, nth=1, **extra)

ウィンドウ内のオフセットnth(正の値である必要があります)を基準にして行を計算します。 行が存在しない場合はNoneを返します。

一部のデータベースでは、存在しないn番目の値を異なる方法で処理する場合があります。 たとえば、Oracleは、文字ベースの式に対してNoneではなく空の文字列を返します。 このような場合、Djangoは変換を行いません。


Ntile

class Ntile(num_buckets=1, **extra)

frame句の各行のパーティションを計算し、1とnum_bucketsの間で可能な限り均等に数値を分散します。 行が複数のバケットに均等に分割されていない場合、1つ以上のバケットがより頻繁に表されます。


PercentRank

class PercentRank(*expressions, **extra)

frame句の行のパーセンタイルランクを計算します。 この計算は、以下を評価することと同等です。

(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


Rank

class Rank(*expressions, **extra)

RowNumberと比較して、この関数はウィンドウ内の行をランク付けします。 計算されたランクにはギャップが含まれています。 DenseRank を使用して、ギャップのないランクを計算します。


RowNumber

class RowNumber(*expressions, **extra)

ウィンドウフレームのパーティション化がない場合は、フレーム句の順序またはクエリ全体の順序に従って行番号を計算します。