Ajax Django-如何以固定的间隔进行API调用
我想做什么: 我构建了一个仪表板,其中显示了我从Zendesk.com上的API获得的关键性能指标。它需要定期更新(我正试图使用time.sleep()来完成这项工作),但不能太频繁,因为我每分钟有700个请求限制。我使用了Django,因此我可以创建一个界面来显示数据。它永远不会被用作网站 问题: 我使用jquery“get”调用从脚本中获取数据。如果我使用“python manage.py runserver”,它最终会创建我猜想的许多工作人员,并且太频繁地调用我的脚本,并且超过了Zendesk的700个请求限制。如果我使用“python manage.py runserver--nothreading”,它工作得很好,但是当我单击导航栏中的按钮或尝试刷新页面时,我必须等待脚本完全运行,然后才能开始执行任务 我的程序的相关代码: 例如,在html代码中,我从json调用数据:Ajax Django-如何以固定的间隔进行API调用,ajax,django,Ajax,Django,我想做什么: 我构建了一个仪表板,其中显示了我从Zendesk.com上的API获得的关键性能指标。它需要定期更新(我正试图使用time.sleep()来完成这项工作),但不能太频繁,因为我每分钟有700个请求限制。我使用了Django,因此我可以创建一个界面来显示数据。它永远不会被用作网站 问题: 我使用jquery“get”调用从脚本中获取数据。如果我使用“python manage.py runserver”,它最终会创建我猜想的许多工作人员,并且太频繁地调用我的脚本,并且超过了Zende
<script type="text/javascript">
$(document).ready(function() {
function pollSiteData () {
$.get('/nb_new/', function(resp) {
$('#nb_new').text(resp['nb_new']);
});
window.setTimeout(pollSiteData,10000);
}
pollSiteData();
});
</script>
视图如下(xxxxxx是我的登录信息,用于测试):
上面基于类的视图从我创建的文件engine.py调用函数“main”
功能是:
def main(*args):
client = ZenClient(args)
time.sleep(45)
print("Next iteration")
return get_infos(client, "open", "pending", "new")
主函数调用get_infos,它返回一个我转换为json的命令
def get_infos(client, status, status2, status3):
#Script that downloads stats from Zendesk
return {"nb_new": str(len(filtered_new_tickets))}
当我运行“python manage.py runserver”时,我们可以看到它过于频繁地使用我的脚本:
Next iteration
Next iteration
Next iteration
[09/May/2018 08:01:21] "GET /nb_new/ HTTP/1.1" 200 86
Next iteration
[09/May/2018 08:01:30] "GET /nb_new/ HTTP/1.1" 200 86
Next iteration
[09/May/2018 08:01:35] "GET /nb_new/ HTTP/1.1" 200 86
Next iteration
[09/May/2018 08:01:51] "GET /nb_new/ HTTP/1.1" 200 86
[09/May/2018 08:02:04] "GET /nb_new/ HTTP/1.1" 200 86
Next iteration
当我使用“python manage.py runserver--nothreading”时,它会以很好的间隔进行调用,但界面上的按钮没有响应。(我想是因为它必须先完成脚本,然后才能确认按下按钮。)
这是我的界面图片(“nb_new”更新“支持需求响应”旁的票证数量)
结论/问题:我如何确保我的脚本只运行一次,比如说每分钟15秒一次,但仍然让界面响应按钮的按下或刷新页面?请尽量避免给出需要我使用完全不同框架的解决方案。不幸的是,时间是一种非常稀缺的资源。这里有一个简单的解决方案:
存储新更新的更简单方法是仅为这些数据创建专用模型。创建此模型的一个实例,只要在新数据到达时不断更新其状态(字段值),而不是每次都创建单独的对象。然后,从您的视图中,无论何时收到jQuery调用,都可以返回这个对象 如果不喜欢使用这种模型和数据库方法,可以使用基于内存的数据库(队列)存储脚本中的数据,然后从Django视图访问它。为此,我推荐Redis
示例脚本:
# start_server.py
import subprocess
import threading
import time
def ping():
while True:
print("Pinging ...") # do actual API pinging stuff here
time.sleep(10)
t = threading.Thread(target=ping)
t.start() # this will run the `ping` function in a separate thread
# now start the django server
subprocess.call(['python', 'manage.py', 'runserver'])
现在,您所要做的就是运行
python start\u server.py
,它将自动运行Django服务器和API ping函数。您考虑过了吗?你可以让一个工人运行,这是你想要做的,对吗?谢谢你的建议。我真正不喜欢芹菜的地方是,我必须安装几个依赖项,这样我就不能轻松地将它打包成一个.exe文件并在另一台计算机上运行。如果这是我唯一的选择,你能给我一个想法(至少从起点)我将如何编码到这个程序?嗯,是的,这似乎非常有用。我将使用您的模型策略来避免外部依赖。因此,我需要我的engine.py脚本在后台运行,而无需从我的网页界面调用。最好的方法是什么?是否有一种方法可以在某个地方引用它,以便在我使用runserver时它就开始工作?谢谢你的帮助,这是一个很好的建议。@Shezmula我用一个小示例代码更新了答案。
Next iteration
Next iteration
Next iteration
[09/May/2018 08:01:21] "GET /nb_new/ HTTP/1.1" 200 86
Next iteration
[09/May/2018 08:01:30] "GET /nb_new/ HTTP/1.1" 200 86
Next iteration
[09/May/2018 08:01:35] "GET /nb_new/ HTTP/1.1" 200 86
Next iteration
[09/May/2018 08:01:51] "GET /nb_new/ HTTP/1.1" 200 86
[09/May/2018 08:02:04] "GET /nb_new/ HTTP/1.1" 200 86
Next iteration
# start_server.py
import subprocess
import threading
import time
def ping():
while True:
print("Pinging ...") # do actual API pinging stuff here
time.sleep(10)
t = threading.Thread(target=ping)
t.start() # this will run the `ping` function in a separate thread
# now start the django server
subprocess.call(['python', 'manage.py', 'runserver'])