1

当我尝试通过管理员将我的两个模型中的日期时间字段设置为今天的日期时,我收到错误“无法在时区 America/Los_Angeles 中解释;它可能不明确或可能不存在”。这只发生在这两种模型中。如果我尝试在其他模型中将 datetime 设置为今天的日期(其中大部分未显示),则没有问题。

以下是 model.py 中的相关模型:

from django.db import models

# DateTimeField has no problem with today's date in this model
class Subject(models.Model):
    title = models.CharField(max_length=200, unique=True)
    date_created = models.DateTimeField('date created')
    times_viewed = models.IntegerField()

# Both DateTimeFields give an error in this model
class Discussion(models.Model):
    subject = models.ForeignKey(Subject)

    title = models.CharField(max_length=200)
    version = models.CharField(max_length=200)
    created = models.DateTimeField('date created')
    updated = models.DateTimeField('date updated')
    creator = models.CharField(max_length=200)

# DateTimeField gives an error in this model too
class DiscussionPost(models.Model):
    discussion = models.ForeignKey(Discussion)

    poster = models.CharField(max_length=200)
    text = models.TextField()
    posted = models.DateTimeField('date posted')

这是 admin.py 的相关部分:

from django.contrib import admin
from my_app.models import Subject, Discussion, DiscussionPost # and other irrelevant models

class DiscussionPostInline(admin.StackedInline):
    model = DiscussionPost
    extra = 1

class DiscussionAdmin(admin.ModelAdmin):
    fieldsets = [
        ('Title',        {'fields': ['title']}),
        ('Creator',      {'fields': ['creator']}),
        ('Date Created', {'fields': ['created']}),
        ('Date Updated', {'fields': ['updated']}),
    ]
    inlines = [DiscussionPostInline]
    list_display = ('title', 'creator', 'created', 'updated')

admin.site.register(Discussion, DiscussionAdmin)

DiscussionInline(admin.StackedInline):
    model = Discussion
    extra = 1

SubjectAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,              {'fields': ['title']}),
        ('Times Viewed',    {'fields': ['times_viewed'], 'classes': ['collapse']}),
        ('Date Created',    {'fields': ['date_created'], 'classes': ['collapse']}),
    ]
    inlines = [DiscussionInline]
    list_display = ('title', 'times_viewed', 'date_created')
    list_filter = ['date_created']
    search_fields = ['title']
    date_hierarchy = 'date_created'

admin.site.register(Subject, SubjectAdmin)

如果我从管理员手动更改为不同的日期,我不会收到错误消息。就在我使用今天的日期时(手动和使用 now() )。有人知道为什么会这样吗?

此管理结构基于此Django Admin nested inline的第二个答案。

更新我在管理员中更改了日期时间,现在它可以工作了。我没有更改模型或管理中的任何内容,所以我很难理解为什么今天早上早些时候它没有工作。

4

1 回答 1

2

在 USE_TZ = True 时,您一直在混淆天真的日期时间对象。要创建当前时间,您需要使用timezone.now()而不是datetime.now()

来自pytz 文档

我们必须处理的主要问题是某些日期时间可能在一年中出现两次。...这意味着,如果您尝试使用标准日期时间语法在“美国/东部”时区创建时间,则无法指定您的意思是在夏令时结束时间转换之前还是之后.

...

最好和最简单的解决方案是坚持使用 UTC。pytz 包通过在 Python 文档中包含基于标准 Python 参考实现的特殊 UTC 实现,鼓励使用 UTC 表示内部时区。

...

如果您将 None 作为 is_dst 标志传递给 localize(),如果您尝试构建模棱两可或不存在的时间,pytz 将拒绝猜测并引发异常。

来自django 文档

天真的日期时间对象的解释

当 USE_TZ 为 True 时,Django 仍然接受天真的日期时间对象,以保持向后兼容性。当数据库层收到一个时,它会尝试通过在默认时区解释它来使其知道并发出警告。

不幸的是,在 DST 转换期间,某些日期时间不存在或不明确。在这种情况下, pytz 会引发异常。其他 tzinfo 实现,例如在未安装 pytz 时用作后备的本地时区,可能会引发异常或返回不准确的结果。这就是为什么您应该在启用时区支持时始终创建可感知的日期时间对象。

在实践中,这很少成为问题。Django 为您提供模型和表单中的日期时间对象,并且最常见的是,新的日期时间对象是通过 timedelta 算法从现有对象创建的。通常在应用程序代码中创建的唯一日期时间是当前时间,timezone.now() 会自动执行正确的操作。

于 2013-11-03T20:14:31.887 回答