urls.py 中的 Django 时区逻辑和通用视图引发错误,但它是视图、字段还是我?

Posted

技术标签:

【中文标题】urls.py 中的 Django 时区逻辑和通用视图引发错误,但它是视图、字段还是我?【英文标题】:Django timezone logic and Generic View in urls.py raise an error, but is it the view, the field or me? 【发布时间】:2012-09-05 20:48:56 【问题描述】:

我的博客是用 Django 1.4.1 构建的。该博客没有什么特别之处,主要是 Django 教程和书籍中的示例。数据库是 PostgreSQL。我尝试使用尽可能多的通用东西,包括站点地图框架。不幸的是,生成的站点地图显示时区问题。

博客条目模型中的字段“pub_date”具有 DateTimeField 类型。博客的时区是“欧洲/阿姆斯特丹”。如果我在博客管理界面中输入日期和时间,则数据库中的列具有正确的值(例如 2012 JUL 10 00:00 管理界面 => 2012 JUL 09 22:00 UTC PostgreSQL)。函数 Blog.get_absolute_url() 确实产生 /2012/07/09/slug。我希望 UTC 日期(这对我来说很好)

我的 urls.py 就像所有的例子一样。

info_dict = 
    'queryset': Blog.objects.all(),
    'date_field': 'pub_date',
    

url(r'^(?P<year>\d4)/(?P<month>\w3)/(?P<day>\d2)/(?P<slug>[-\w]+)/$', 'django.views.generic.date_based.object_detail', info_dict),

(注意:我在这里使用基于函数的通用视图,但我也尝试了基于类的视图。这两个视图确实产生了相同的问题)。

问题是:可以使用 get_absolute_url() 中的值找到每个博客条目,但不能找到具有不同本地时区日期和 UTC 的条目(例如 2012 年 7 月 10 日 00:00 本地 => 2012 年 7 月 9 日22:00 UTC)。我确实得到了一个“404”,并且 - 使用 runserver 运行时 - 错误是 RuntimeWarning: DateTimeField received a naive datetime (2012-07-09 23:59:59.999999) while time zone support is active .

我在网上的搜索确实显示了很多关于 Django 时区问题的帖子。它们中的大多数确实与基于日期的档案的月份格式有关。我正在使用最新的 Django 版本 1.4.1 进行大多数修复。我在 date_based.object_detail 或与时区相关的 DateDetailView 的教程或书籍中没有找到任何示例。目前,我对正确的方法有疑问。

可能不是个好主意

    我可以放松“时区”意识 (USE_TZ = False),但这是在忽略问题 我可以更改 *get_absolute_url()* 以生成本地时区的日期(在此示例中为 2012/07/10/slug),但随后我将数据库格式和用户格式混为一谈

不知道这是否是一个好(或可行)的想法

    使用字典 info_dict 执行某些操作以告知通用视图 pub_date 是 UTC 格式。我找不到这样做的方法 使用字典来更改日期时间格式(例如 pub_date.date),但这会产生语法错误。此外,Django 文档说通用视图支持 DateField 和 DateTimeField

有什么好方法吗?关注 pub_date 以转换为 DateField,处理视图以接受 DateTimeField,从通用视图切换到自制视图,还是其他?

Django 解决此问题的最常用方法是什么?

【问题讨论】:

现在,我正在切换到对象 ID。我更改了 blog.get_absolute_url() 以返回 id (self.id)。在 urls.py 中,我使用 django.views.generic.DetailView。正则表达式在 url 中找到 id 并将其命名为 。这一切都很好。 我的下一步是使用基于日期的存档通用视图。我看到很多关于 Django 的时区感知的博客、笔记、cmets 等。我仍然不明白这是否行不通,或者我不明白这些东西。所以需要更多的实验 【参考方案1】:

我已经为这个确切的问题苦苦挣扎了几个小时。关键是我的 get_absolute_url 逻辑导致 UTC 响应,但 DateDetailView 期望 URL 与本地时区匹配。

对于 get_absolute_url,我的解决方案如下:

from django.utils import timezone

class MyModel(models.Model):
# Other model code here

def _get_absolute_url(self):
    local_pub_date = timezone.localtime(self.entry.pub_date)
    return ('%sblog_detail', (), 
        'year': local_pub_date.year,
        'month': local_pub_date.strftime('%m'),
        'day': local_pub_date.strftime('%d'),=
        'slug': self.slug
    )
get_absolute_url = models.permalink(_get_absolute_url)

这似乎适用于我的目的。不过,我的所有用户都在同一个时区,因此它可能不适合具有更多样化用户群的网站。

-PT

【讨论】:

【参考方案2】:

我遇到了同样的问题,因为我的 get_absolute_url 显示的是下一个日期。我到处搜索,找不到任何可以帮助最新 Django 版本的东西。我对您的唯一建议是将日期和时间设置为数据库中的单独字段。

【讨论】:

检查您的数据库。我确实使用 Postgresql。如文件所述,pub_date 列(是日期时间)具有 UTC 和差异。我的 get_absolute_url 总是显示 UTC。 我不想从日期时间切换到日期和时间。从技术上讲,一切正常,只是没有为这个问题选择标准。现在,我切换到对象 id 没问题。 我检查了 mysql 设置,它使用 UTC,但我的软件时区是 PDT。当 PDT 和 UCT 的日期仍然相同时,我尝试过,但是当它通过模板显示时,则显示错误。在我的研究中,我发现有人说要这样做并且它解决了我遇到的其他日期/时间问题......我对 Django 还太陌生,无法完全理解为什么这解决了这个问题: date_list_utc = blogpost.objects.filter ().dates('blog_pub_date','month') date_list = [] for datetimeobj in date_list_utc: dateobj = datetimeobj.date() date_list.append(dateobj)

以上是关于urls.py 中的 Django 时区逻辑和通用视图引发错误,但它是视图、字段还是我?的主要内容,如果未能解决你的问题,请参考以下文章

Django:使用 urls.py 进行分页

在 Django 中过滤 Queryset 并设计正确的 urls.py 和模板

刷新 django 中的 urls.py 缓存

项目中的每个 django 应用程序都应该有自己的 urls.py 吗?

DJango 中 URLS.py 中的无效语法错误

django中urls.py中的include()是什么