Django 1.11-如何确保TruncYear产生祖鲁时间

问题描述 投票:0回答:2

我正在使用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}]>

如果我将其序列化,则会产生此:

serializer.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']

输出:

[
    {
      "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查询集在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但是几小时后,它开始产生像这样的时区timeformat 2017-01-01T00:00:00 + 03:00

我还注意到如果我重新启动服务器,它将没有Z时间。我必须做supervisorctl停止然后再启动,然后暂时似乎可以解决它。

这是我的主管重启代码段

/home/user/myapp/gunicorn_start.bash
/etc/supervisor/conf.d/myapp.conf
https://gist.github.com/axilaris/01525b78fcdc03071fcd34818820d7f1

这是我的服务器版本Ubuntu 16.04.3 LTS

可能是什么问题,以及如何解决它,以使其持续产生祖鲁时间。

python django postgresql datetime django-1.11
2个回答
0
投票

我已经检查了Django Rest Framework的来源,看起来它默认为current timezone使用“ DateTimeField”,但是您可以通过传递等于default_timezone"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'))

似乎在您的源代码中您覆盖了“当前时区”,但未将其设置为默认时区或其他,这就是为什么它在服务器重新启动后立即工作并在数小时内停止(当请求设置了错误的时机)时区)。因此,您有2种解决方法-像我上面一样使用default_timezone参数声明您的字段,或查找当前时区值的更改位置)。对于这种情况,最简单的解决方案当然是声明所需的字段时区,但总的来说,它当然应该没有错误:)

更多信息:


0
投票

我在这里指出的第一件事是,您正在使用serializers.DateTimeField--DRF doc字段表示year

© www.soinside.com 2019 - 2024. All rights reserved.