如何使用Django在Postgres数据库中接受时区

时间:2017-05-02 22:30:16

标签: django postgresql datetime timezone celery

我有一个模特

models.py

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models

from django.utils import timezone

class Article(models.Model):
     sort = models.IntegerField(blank=True)
     pub_date = models.DateTimeField(default=timezone.now)
     title = models.CharField(max_length=30, blank=True)

common.py

 TIME_ZONE = 'America/New_York'
 USE_TZ = True

local.py

 from .common import *

 CELERY_BROKER_URL = env('REDIS_URL')
 CELERY_RESULT_BACKEND = env('REDIS_URL')

 CELERY_ACCEPT_CONTENT = ['application/json']
 CELERY_TASK_SERIALIZER = 'json'
 CELERY_RESULT_SERIALIZER = 'json'
 CELERY_TIMEZONE = TIME_ZONE

production.py

 from .common import *

 CELERY_BROKER_URL = env('REDIS_URL')
 CELERY_RESULT_BACKEND = env('REDIS_URL')

 CELERY_ACCEPT_CONTENT = ['application/json']
 CELERY_TASK_SERIALIZER = 'json'
 CELERY_RESULT_SERIALIZER = 'json'
 CELERY_TIMEZONE = TIME_ZONE

tasks.py

 from __future__ import absolute_import, unicode_literals
 from celery.decorators import task

 from .models import Article

 import urllib2
 import json
 import datetime

 @task(name="articles")
 def update_article():

 # .... more code
 article = Article.objects.get(id=1)
       if article != None:
            article.pub_date = datetime.datetime.now()
            article.title = "Hello"
            article.save()

当我在django shell中运行时

 import datetime
 pub_date = datetime.datetime.now()
 print pub_date

pub_date是EST /' America / New_York'时区 - 正确。

我有芹菜更新文章,我写了一个简单的代码

article.pub_date = datetime.datetime.now()

当pub_date更新时,在数据库中日期是UTC而不是America / New_York / EST时区,即使shell显示正确的ETC,但运行它与任务,在postgres DB中它是UTC

1 个答案:

答案 0 :(得分:1)

以下评论=)

始终使用django.utils.timezone.now()代替datetime.datetime.now()

请注意,直接在Postgres中,您将看到UTC + TZ offset格式的这些日期时间列,Django会将日期时间转换为所需的时区(如果时间在视图中呈现,则为服务器TZ或客户端TZ)

现在,如果在你的本地Django shell中你看到正确的日期时间而不是在Heroku中,可能是Heroku列没有保存TZ信息(虽然我发现这很难相信)。我没有使用过Heroku,但是Django迁移会处理timestamp with time zone列。在postgres中,您可以通过psql(或dbshel​​l)检查列的类型:

\d <your table>

                   Table article
    Column     |           Type            |        Modifiers
---------------+---------------------------+---------------------
 id            | integer                   | ...
 pub_date      | timestamp with time zone  | ...
 ....          | ...                       | ...

希望这有帮助。