1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
import datetime
from django import forms
TIMEFIELD_TRANSFORM_EXPRESSIONS = {"hour", "minute", "second"}
DATEFIELD_TRANSFORM_EXPRESSIONS = {
"year",
"iso_year",
"month",
"day",
"week",
"week_day",
"iso_week_day",
"quarter",
}
DATETIMEFIELD_TRANSFORM_EXPRESSIONS = (
{"date", "time"}
| TIMEFIELD_TRANSFORM_EXPRESSIONS
| DATEFIELD_TRANSFORM_EXPRESSIONS
)
TRANSFORM_FIELD_TYPES = {
"year": forms.IntegerField,
"iso_year": forms.IntegerField,
"month": forms.IntegerField,
"hour": forms.IntegerField,
"minute": forms.IntegerField,
"second": forms.IntegerField,
"day": forms.IntegerField,
"week": forms.IntegerField,
"week_day": forms.IntegerField,
"iso_week_day": forms.IntegerField,
"quarter": forms.IntegerField,
"date": forms.DateField,
"time": forms.TimeField,
}
def derive_from_value(value, expr):
if isinstance(value, datetime.datetime):
return derive_from_datetime(value, expr)
if isinstance(value, datetime.date):
return derive_from_date(value, expr)
if isinstance(value, datetime.time):
return derive_from_time(value, expr)
return None
def derive_from_time(value, expr):
"""
Mimics the behaviour of the ``hour``, ``minute`` and ``second`` lookup
expressions that Django querysets support for ``TimeField`` and
``DateTimeField``, by extracting the relevant value from an in-memory
``time`` or ``datetime`` value.
"""
if expr == "hour":
return value.hour
if expr == "minute":
return value.minute
if expr == "second":
return value.second
raise ValueError(
"Expression '{expression}' is not supported for {value}".format(
expression=expr, value=repr(value)
)
)
def derive_from_date(value, expr):
"""
Mimics the behaviour of the ``year``, ``iso_year`` ``month``, ``day``,
``week``, ``week_day``, ``iso_week_day`` and ``quarter`` lookup
expressions that Django querysets support for ``DateField`` and
``DateTimeField`` columns, by extracting the relevant value from an
in-memory ``date`` or ``datetime`` value.
"""
if expr == "year":
return value.year
if expr == "iso_year":
return value.isocalendar()[0]
if expr == "month":
return value.month
if expr == "day":
return value.day
if expr == "week":
return value.isocalendar()[1]
if expr == "week_day":
v = value.isoweekday()
return 1 if v == 7 else v + 1
if expr == "iso_week_day":
return value.isoweekday()
if expr == "quarter":
return (value.month - 1) // 3 + 1
raise ValueError(
"Expression '{expression}' is not supported for {value}".format(
expression=expr, value=repr(value)
)
)
def derive_from_datetime(value, expr):
"""
Mimics the behaviour of the ``date``, ``time`` and other lookup
expressions that Django querysets support for ``DateTimeField`` columns,
by extracting the relevant value from an in-memory ``datetime`` value.
"""
if expr == "date":
return value.date()
if expr == "time":
return value.time()
if expr in TIMEFIELD_TRANSFORM_EXPRESSIONS:
return derive_from_time(value, expr)
if expr in DATEFIELD_TRANSFORM_EXPRESSIONS:
return derive_from_date(value, expr)
raise ValueError(
"Expression '{expression}' is not supported for {value}".format(
expression=expr, value=repr(value)
)
)
|