apache Django 应用程序中的 datetime.now() 变坏了

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/883823/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 17:38:07  来源:igfitidea点击:

datetime.now() in Django application goes bad

pythondjangoapachedatetimemod-wsgi

提问by Nixarn

I've had some problems with a Django application after I deployed it. I use a Apache + mod-wsgi on a ubuntu server. A while after I reboot the server the time goes foobar, it's wrong by around -10 hours. I made a Django view that looks like:

部署 Django 应用程序后,我遇到了一些问题。我在 ubuntu 服务器上使用 Apache + mod-wsgi。在我重新启动服务器一段时间后,时间变为 foobar,大约 -10 小时是错误的。我做了一个 Django 视图,如下所示:

def servertime():
  return HttpResponse( datetime.now() )

and after I reboot the server and check the url that shows that view it first looks alright. Then at one point it sometimes gives the correct time and sometimes not and later it gives the wrong time always. The server time is corect though.

在我重新启动服务器并检查显示该视图的 url 后,它首先看起来没问题。然后在某一时刻它有时给出正确的时间,有时不给出,后来它总是给出错误的时间。服务器时间是正确的。

Any clues? I've googled it without luck.

有什么线索吗?我在没有运气的情况下用谷歌搜索了它。

采纳答案by Nixarn

I found that putting wsgi in daemon mode works. Not sure why, but it did. Seems like some of the newly created processes gets the time screwed up.

我发现将 wsgi 置于守护进程模式是可行的。不知道为什么,但确实如此。似乎一些新创建的进程把时间搞砸了。

回答by phillc

Can I see your urls.py as well?

我也可以看看你的 urls.py 吗?

Similar behaviors stumped me once before...

类似的行为之前曾让我难堪...

What it turned out to be was the way that my urls.py called the view. Python ran the datetime.now() once and stored that for future calls, never really calling it again. This is why django devs had to implement the ability to pass a function, not a function call, to a model's default value, because it would take the first call of the function and use that until python is restarted.

结果是我的 urls.py 调用视图的方式。Python 运行了一次 datetime.now() 并将其存储以备将来调用,不再真正调用它。这就是 django 开发人员必须实现将函数而不是函数调用传递给模型默认值的能力的原因,因为它会进行函数的第一次调用并使用它,直到重新启动 python。

Your behavior sounds like the first time is correct because its the first time the view was called. It was incorrect at times because it got that same date again. Then it was randomly correct again because your apache probably started another worker process for it, and the craziness probably happens when you get bounced in between which process was handling the request.

您的行为听起来第一次是正确的,因为这是第一次调用视图。有时它是不正确的,因为它再次得到了相同的日期。然后它再次随机正确,因为您的 apache 可能为它启动了另一个工作进程,并且当您在处理请求的进程之间被反弹时,可能会发生疯狂。

回答by David

datetime.now() is probably being evaluated once, when your class is instantiated. Try removing the parenthesis so that the function datetime.now is returned and THEN evaluated. I had a similar issue with setting default values for my DateTimeFields and wrote up my solution here.

datetime.now() 可能正在评估一次,当您的类被实例化时。尝试删除括号,以便返回函数 datetime.now 并评估 THEN。我在为 DateTimeFields 设置默认值时遇到了类似的问题,并在此处编写了我的解决方案。

回答by Xbito

Maybe the server is evaluating the datetime.now() at server start, try making it lazy through a template or use a variable in your view.

也许服务器在服务器启动时评估 datetime.now(),尝试通过模板使其延迟或在您的视图中使用变量。

Take a look at this blog post.

看看这篇博文

回答by Klaas van Schelven

Django sets the system time zone based on your settings variable TIME_ZONE. This may lead to all kinds of confusion when running multiple Django instances with different TIME_ZONE settings.

Django 根据您的设置变量 TIME_ZONE 设置系统时区。这可能会导致在运行具有不同 TIME_ZONE 设置的多个 Django 实例时出现各种混乱。

This is what Django does:

这就是 Django 所做的:

os.environ['TZ'] = self.TIME_ZONE

The above answer:

上面的回答:

"I found that putting wsgi in daemon mode works"

“我发现将 wsgi 置于守护进程模式是可行的”

does not work for me...

对我不起作用...

I think I'm going with not using django's built in TIME_ZONE anymore.

我想我不再使用 django 内置的 TIME_ZONE 了。

回答by Jiaaro

you may need to specify the content type like so

您可能需要像这样指定内容类型

def servertime():
  return HttpResponse( datetime.now(), content_type="text/plain" )

another idea:

另一个想法:

it may not be working because datetime.now() returns a datetime object. Try this:

它可能不起作用,因为 datetime.now() 返回一个日期时间对象。尝试这个:

def servertime():
  return HttpResponse( str(datetime.now()), content_type="text/plain" )

回答by Blas

Try to set your time zone (TIME_ZONE variable) in settings.py

尝试在 settings.py 中设置您的时区(TIME_ZONE 变量)

That worked for me.

那对我有用。