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

How to accept timezone in Postgres database using Django

我有模型

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 数据库中它是 UTC

关注评论=)

始终使用 django.utils.timezone.now() 而不是 datetime.datetime.now()

请注意,直接在 Postgres 中,您会看到这些 UTC + TZ offset 格式的日期时间列,Django 会将日期时间转换为所需的时区(如果时间以查看)。

现在,如果您在本地 Django shell 中看到正确的日期时间,但在 Heroku 中却看不到,则可能是 Heroku 的列不包含 TZ 信息(尽管我觉得这很难相信)。我没有使用过 Heroku,但 Django 迁移会处理 timestamp with time zone 列。在 postgres 中,您可以通过 psql(或 dbshell)检查列的类型:

\d <your table>

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

希望对您有所帮助。