Axi*_*xil 3 python django postgresql datetime django-1.11
我正在使用 Django 1.11 和 Postgres 9.4。
如何确保 TruncYear 生成祖鲁语时间 (2019-10-01T00:00:00Z)。我注意到它用这样的时区创建日期时间 (2017-01-01T00:00:00+03:00)
这是我的 TruncYear 查询集代码:
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}]>
Run Code Online (Sandbox Code Playgroud)
如果我序列化它会产生这个:
序列化程序.py
class TimeseriesYearSerializer(serializers.ModelSerializer):
venue = VenueTSSerializer(read_only=True)
year = serializers.DateTimeField(read_only=True)
count = serializers.IntegerField(read_only=True)
class Meta:
model = Tracking
fields = ['venue', 'year', 'count']
Run Code Online (Sandbox Code Playgroud)
输出:
[
{
"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
}
]
Run Code Online (Sandbox Code Playgroud)
如何确保 TruncYear 查询集在祖鲁语时间中生成日期时间字符串,如 2019-10-01T00:00:00Z 而不是时区 2019-01-01T00:00:00+03:00。
更新:我注意到我通过重新启动 django 服务临时解决了这个问题。
sudo supervisorctl stop all
sudo supervisorctl start all
Run Code Online (Sandbox Code Playgroud)
然后它能够产生这样的 Z 时间 2019-10-01T00:00:00Z 但是几个小时后,它开始产生这样的时区时间格式 2017-01-01T00:00:00+03:00
我还注意到如果我重新启动服务器,它不会有 Z 时间。我必须执行 supervisorctl stop 和 start 然后它似乎暂时修复它。
这是我的主管重启的代码片段
/home/user/myapp/gunicorn_start.bash
/etc/supervisor/conf.d/myapp.conf
https://gist.github.com/axilaris/01525b78fcdc03071fcd34818820d7f1
Run Code Online (Sandbox Code Playgroud)
这是我的服务器版本 Ubuntu 16.04.3 LTS
可能是什么问题以及如何解决它,以便它始终如一地产生祖鲁语时间。
我在这里注意到的第一件事是,您使用serializers.DateTimeField--DRF doc字段表示年份,其中年份始终是正整数。
关于时区问题,Django在从数据库查询时使用这些TIME_ZONE设置。这是 postgress 中最小的 SQL 查询,当你这样做时,
SELECT a,b,c,DATE_TRUNC('year', "tracking_table"."created_at" AT TIME ZONE 'YOUR_TIME_ZONE_VALUE') AS "year" FROM "tracking_tableRun Code Online (Sandbox Code Playgroud)
但是,幸运的是,您可以在类中的参数的帮助下指定目标时区(在您的情况下,它的 UTC)。tzinfoTruncYear
import pytz
Tracking.objects.annotate(year=TruncYear('created_at', tzinfo=pytz.UTC))Run Code Online (Sandbox Code Playgroud)
要在 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']Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
141 次 |
| 最近记录: |