Django - 如何在一定时间后调用函数

时间:2015-08-20 02:03:24

标签: python django function

#In my views.py file
def home(request):

    myfunc()

    return render(request, "home.html", {})

home.html加载需要一段时间,因为每次点击它都会执行函数myfunc。有没有办法在访问home.html之前在服务器上加载myfunc,以便加载更快。还有可能每15分钟调用一次myfunc,而不是每次访问home.html时都会调用吗?

2 个答案:

答案 0 :(得分:4)

  

有没有办法在home.html之前在服务器上加载myfunc   访问,以便加载更快。还有可能有myfunc   每15分钟调用一次而不是每次访问home.html?

我认为你有三种方法可以解决这个问题:

1)缓存

使用缓存,您只需隐藏繁重计算的结果,以便在第一次之后保存。这里的好处是它非常易于使用,易于设置且速度非常快,但是第一次访问它(并且每次它被无效)它都会被它用掉。速度很慢,你可以在缓存中存储的大小有限(在memcached的情况下通常为1MB)。

获得cache server setup后,通常可以使用Django's decorator

from django.views.decorators.cache import cache_page

@cache_page(60 * 15)
def my_view(request):

在您的情况下,您似乎并未实际使用myfunc的结果,因此您没有任何数据可以实际缓存?因此,缓存不会有太大帮助。

2)Cron

可能更好的解决方案是创建一个调用myfunc的管理命令,然后在服务器的crontab中创建一个条目,每15分钟运行一次。

让我们说你有一个名为update_myfunc的Django管理命令。然后,您可以编辑服务器的crontab并添加如下所示的行:

*/15 * * * * /location/of/python /var/www/yourproject/manage.py update_myfunc

这将在您编辑crontab的任何服务器上每15分钟运行一次命令。 (要编辑crontab,请输入命令crontab -e

3)芹菜

您也可以使用Celery异步运行此命令,甚至可以使用celerybeat代替上面的cron条目。

要执行此操作,您需要安装消息队列(Redis非常容易安装),然后您需要在设置文件中对其进行配置。您还需要Celery Python库,然后您需要让Celery作为工作者或通过celerybeat在该服务器上运行(可能是您想要的celerybeat)。

4)上述

的组合

还有第四种选择,即将上述部分内容结合起来。例如,假设myfunc进行了一系列计算,这些计算存储在数据库中,然后它组装了它已计算的数据,以某种方式在视图中使用。

在这种情况下,您可以将其功能分为两部分:计算部分和视图帮助部分。然后,您可以每隔十五分钟使用celery或cron运行计算部分,然后您可以缓存调用视图帮助部分的视图。

此外,如果您没有将此计算存储在数据库中,您实际上可以手动将内容放入缓存中。在这种情况下,您可以在缓存中存储一​​些内容,然后在需要时使用专门创建的缓存密钥进行检索。

答案 1 :(得分:1)

答案取决于:

  1. myfunc()是否与当前请求相关
  2. 如果它与当前请求相关,则响应是否取决于其结果
  3. 如果myfunc()以任何方式与当前请求/会话无关,那么当Django应用程序启动时,它应该全局执行一次,其结果将被缓存以供以后使用。例如,您可以将代码放在urls.py中,这可以保证执行。

    否则,如果myfunc()与当前请求相关,但响应不需要其结果,则可以异步执行(在响应之前返回HTTP响应)。标准解决方案是使用消息队列。阅读Celery,一个Django的消息队列适配器。

    否则如果响应确实取决于myfunc()的结果,除了优化myfunc()之外,您无能为力。

    对于定期执行,也许你想用cron作业来做。另一种方法是使用消息队列,其任务是在执行后将自己置于队列中。