Django的PostgreSQL及注释日期时间字段到的localtime
问题描述:
我使用Django 1.11 PostgreSQL的9.6和JQuery数据表(使用Django-数据表,以提供从Djang模型AJAX数据源Django的PostgreSQL及注释日期时间字段到的localtime
模型例子:
class MyModel(models.Model):
start = models.DateTimeField()
end = = models.DateTimeField()
。PostgreSQL的存储日期时间与时区的信息,这是很好的UTC
我可以重写数据表列渲染正确的数据表呈现的日期时间查看:
if column == "start":
return timezone.localtime(row.start).strftime(STRFTIME_DATETIME_FORMAT)
尝试为部分日期提供搜索过滤器查询时出现的问题。如果我添加注释添加到DATE_STR上搜索:
def filter_queryset(self, qs):
search = self.request.GET.get(u'search[value]', None)
if search:
sql_datetime_format = getattr(settings, "SQL_DATETIME_FORMAT", "DD/MM/YYYY HH24:MI")
qs = qs.annotate(
start_str=Func(F('start'), Value(sql_datetime_format), function='to_char'),
end_str=Func(F('end'), Value(sql_datetime_format), function='to_char'),
)
q_objects = Q()
q_objects |= Q(start_str__icontains=search)
q_objects |= Q(end_str__icontains=search)
qs = qs.filter(q_objects).distinct()
return qs
的start_str和end_str为UTC日期时间不是本地的日期时间转换为字符串。
所以我英国迄今在夏季正确显示为2017年1月6日00:00,但寻找它,你必须输入:31/05/2017 23:00
我似乎无法到找到将start_str和end_str分配给本地时间而不是UTC。
答
为了对付我结束了写我自己的Django表达对PostgreSQL的日期和时间:
from django.db.models import Func
def ToChar(expression, output):
'''
Custom query to convert timestamp to string.
Example usage
queryset.annotate(
created_date_str=ToChar('created_date', 'DD/MM/YYYY HH25:MI')
)
'''
class ToCharWithoutTZ(Func):
function = "TO_CHAR"
template = '%(function)s(%(expressions)s, \'{output}\')'.format(output=output)
return ToCharWithoutTZ(expression)
def ToCharTZ(expression, timezone, output):
'''
Custom query to convert timestamp to string in requested time zone.
Example usage
queryset.annotate(
created_date_str=ToCharTZ('created_date', 'GB', 'DD/MM/YYYY HH25:MI')
)
'''
class ToCharWithTZ(Func):
function = "TO_CHAR"
template = '%(function)s(%(expressions)s AT TIME ZONE \'{timezone}\', \'{output}\')'.format(timezone=timezone, output=output)
return ToCharWithTZ(expression)
用法示例:
from myapp.models.functions import ToCharTZ
def filter_queryset(self, qs):
search = self.request.GET.get(u'search[value]', None)
if search:
sql_datetime_format = getattr(settings, "SQL_DATETIME_FORMAT", "DD/MM/YYYY HH24:MI")
qs = qs.annotate(
start_str=ToCharTZ('start', 'GB', sql_datetime_format),
end_str=ToCharTZ('end', 'GB', sql_datetime_format),
)
q_objects = Q()
q_objects |= Q(start_str__icontains=search)
q_objects |= Q(end_str__icontains=search)
qs = qs.filter(q_objects).distinct()
return qs
答
一些帮助从#django IRC频道我已经在Django的PG-utils包使用DateTZ解决了这个:
要安装:
pip install django-pg-utils
更新代码片段:
from pg_utils.utils import DateTZ
def filter_queryset(self, qs):
search = self.request.GET.get(u'search[value]', None)
if search:
sql_datetime_format = getattr(settings, "SQL_DATETIME_FORMAT", "DD/MM/YYYY HH24:MI")
qs = qs.annotate(
start_str=Func(DateTZ(F('start'), 'GB'), Value(sql_datetime_format), function='to_char'),
end_str=Func(DateTZ(F('end'), 'GB'), Value(sql_datetime_format), function='to_char'),
)
q_objects = Q()
q_objects |= Q(start_str__icontains=search)
q_objects |= Q(end_str__icontains=search)
qs = qs.filter(q_objects).distinct()
return qs
希望这会对其他人有用。
这并没有拉回时间信息,只有DateTZ与日期部分一起工作,请参阅下一个答案。 – Steve