Python Django 1.11-我如何确保TruncYear生产祖鲁时间
我正在使用Django1.11和Postgres9.4 我如何确保TruncYear生产祖鲁时间(2019-10-01T00:00:00Z)。我注意到它创建了带有如下时区的datetime(2017-01-01T00:00:00+03:00) 以下是我的TruncYear查询集代码:Python Django 1.11-我如何确保TruncYear生产祖鲁时间,python,django,postgresql,datetime,django-1.11,Python,Django,Postgresql,Datetime,Django 1.11,我正在使用Django1.11和Postgres9.4 我如何确保TruncYear生产祖鲁时间(2019-10-01T00:00:00Z)。我注意到它创建了带有如下时区的datetime(2017-01-01T00:00:00+03:00) 以下是我的TruncYear查询集代码: from django.db.models import Count from django.db.models.functions import TruncMonth, TruncYear, TruncDay,
from django.db.models import Count
from django.db.models.functions import TruncMonth, TruncYear, TruncDay, TruncHour
tracking_in_timeseries_data = Tracking.objects.annotate(
year=TruncYear('created_at')).values('year', 'venue').annotate(
count=Count('employee_id', distinct = True)).order_by('year')
>>> for exp in tracking_in_timeseries_data:
... print(exp['year'], exp['venue'], exp['count'])
2017-01-01 00:00:00+00:00 4 1
2019-01-01 00:00:00+00:00 2 2
2019-01-01 00:00:00+00:00 3 1
2019-01-01 00:00:00+00:00 4 1
2019-01-01 00:00:00+00:00 5 1
2019-01-01 00:00:00+00:00 6 1
>>> tracking_in_timeseries_data
<QuerySet [{'venue': 4, 'year': datetime.datetime(2017, 1, 1, 0, 0, tzinfo=<UTC>), 'count': 1}, {'venue': 2, 'year': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=<UTC>), 'count': 2}, {'venue': 3, 'year': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=<UTC>), 'count': 1}, {'venue': 4, 'year': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=<UTC>), 'count': 1}, {'venue': 5, 'year': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=<UTC>), 'count': 1}, {'venue': 6, 'year': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=<UTC>), 'count': 1}]>
输出:
[
{
"count": 1,
"year": "2017-01-01T00:00:00+03:00",
"venue_id": 2
},
{
"count": 1,
"year": "2018-01-01T00:00:00+03:00",
"venue_id": 1
},
{
"count": 1,
"year": "2018-01-01T00:00:00+03:00",
"venue_id": 2
},
{
"count": 3,
"year": "2019-01-01T00:00:00+03:00",
"venue_id": 1
},
{
"count": 3,
"year": "2019-01-01T00:00:00+03:00",
"venue_id": 2
}
]
我如何确保TruncYear queryset在Zulu时间生成日期时间字符串,如2019-10-01T00:00:00Z,而不是2019-01-01T00:00:00+03:00时区
更新:
我注意到我通过重新启动django服务临时解决了这个问题
sudo supervisorctl stop all
sudo supervisorctl start all
然后它就能够产生这样的Z时间2019-10-01T00:00:00Z
但几个小时后,它开始生成这样的时区时间格式2017-01-01T00:00:00+03:00
我还注意到,如果我重新启动服务器,它将没有Z时间。我必须先停止再启动,然后它暂时似乎可以修复它
下面是我的代码片段,供主管重新启动
/home/user/myapp/gunicorn_start.bash
/etc/supervisor/conf.d/myapp.conf
https://gist.github.com/axilaris/01525b78fcdc03071fcd34818820d7f1
这是我的服务器版本Ubuntu 16.04.3 LTS
问题可能是什么,以及如何修复它以使其始终生成Zulu时间。我已经检查了Django Rest框架的源代码,它看起来像是默认情况下对
日期时间域使用了“”,但是您可以通过将默认\u时区
等于pytz.timezone('Zulu')”
来强制设置它。这样,它将返回所需时区中的字段值
我已经玩了一点,对我来说,它就像预期的那样工作。例如,对于Europe/Moscow
,对于我的测试序列化程序(在我的项目中),我的输出如下
{
"id": 1,
"title": "test 123",
"level": 0,
"slug": "test-123",
"icon_code": "123",
"image": null,
"brand": false,
"children": [],
"created_at": "2019-12-09T01:55:08.438442+03:00"
}
对于Zulu
时区,我有类似的
{
"id": 1,
"title": "test 123",
"level": 0,
"slug": "test-123",
"icon_code": "123",
"image": null,
"brand": false,
"children": [],
"created_at": "2019-12-08T22:55:08.438442Z"
}
我的测试场声明是
created_at = serializers.DateTimeField(format='iso-8601', default_timezone=pytz.timezone('Zulu'))
在源代码中,您似乎覆盖了“当前时区”,但没有将其设置为默认时区等,这就是为什么它在服务器重新启动后立即工作,并在几个小时后停止(当请求设置错误的时区时)。因此,您有两种方法来修复它-使用default_timezone
param或查找当前时区值的更改位置,如上所述声明字段。当然,这种情况下最简单的解决方案是声明所需的字段时区,但通常情况下,它应该可以正常工作,而不会出现错误:)
更多信息:
- (查看
param)default\u时区
关于时区问题,Django使用while从数据库查询。这是postgress中的最小SQL查询,当您这样做时会发生
SELECT a,b,c,DATE_TRUNC('year', "tracking_table"."created_at" AT TIME ZONE 'YOUR_TIME_ZONE_VALUE') AS "year" FROM "tracking_table
要在json响应中显示年份,请将序列化程序更改为
class TimeseriesYearSerializer(serializers.ModelSerializer):
venue = VenueTSSerializer(read_only=True)
year = serializers.IntegerField(read_only=True, source='year.year')
count = serializers.IntegerField(read_only=True)
class Meta:
model = Tracking
fields = ['venue', 'year', 'count']
class TimeseriesYearSerializer(serializers.ModelSerializer):
地点=VenueTSSerializer(只读=真)
year=serializers.IntegerField(只读=True,source='year.year')
计数=序列化程序。整型字段(只读=真)
类元:
模型=跟踪
字段=[‘地点’、‘年份’、‘计数’]
工具书类
为什么年需要一个
datetime字段而不是IntegerField?我已经实现了这个-Tracking.objects.annotate(year=TruncYear('created_at',tzinfo=pytz.UTC))。我给它一些时间,如果它能坚持,到目前为止,它已经坚持了几个小时。将在明天更新我的插件,你所说的暂停是什么意思?意味着这个解决方案目前正在运行。我只需要像上一个查询集那样观察更长的时间,一天后,它会再次显示时区。到目前为止,它看起来还可以,但我需要观察。太好了…让我知道结果。是的,一天多之后,它仍然得到时间。谢谢。
import pytz
Tracking.objects.annotate(year=TruncYear('created_at', tzinfo=pytz.UTC))
class TimeseriesYearSerializer(serializers.ModelSerializer):
venue = VenueTSSerializer(read_only=True)
year = serializers.IntegerField(read_only=True, source='year.year')
count = serializers.IntegerField(read_only=True)
class Meta:
model = Tracking
fields = ['venue', 'year', 'count']