120 lines
3.5 KiB
Python
120 lines
3.5 KiB
Python
|
|
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)
|
||
|
|
)
|
||
|
|
)
|