Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ajax Django-如何以固定的间隔进行API调用_Ajax_Django - Fatal编程技术网

Ajax Django-如何以固定的间隔进行API调用

Ajax Django-如何以固定的间隔进行API调用,ajax,django,Ajax,Django,我想做什么: 我构建了一个仪表板,其中显示了我从Zendesk.com上的API获得的关键性能指标。它需要定期更新(我正试图使用time.sleep()来完成这项工作),但不能太频繁,因为我每分钟有700个请求限制。我使用了Django,因此我可以创建一个界面来显示数据。它永远不会被用作网站 问题: 我使用jquery“get”调用从脚本中获取数据。如果我使用“python manage.py runserver”,它最终会创建我猜想的许多工作人员,并且太频繁地调用我的脚本,并且超过了Zende

我想做什么: 我构建了一个仪表板,其中显示了我从Zendesk.com上的API获得的关键性能指标。它需要定期更新(我正试图使用time.sleep()来完成这项工作),但不能太频繁,因为我每分钟有700个请求限制。我使用了Django,因此我可以创建一个界面来显示数据。它永远不会被用作网站

问题: 我使用jquery“get”调用从脚本中获取数据。如果我使用“python manage.py runserver”,它最终会创建我猜想的许多工作人员,并且太频繁地调用我的脚本,并且超过了Zendesk的700个请求限制。如果我使用“python manage.py runserver--nothreading”,它工作得很好,但是当我单击导航栏中的按钮或尝试刷新页面时,我必须等待脚本完全运行,然后才能开始执行任务

我的程序的相关代码:

例如,在html代码中,我从json调用数据:

     <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秒一次,但仍然让界面响应按钮的按下或刷新页面?请尽量避免给出需要我使用完全不同框架的解决方案。不幸的是,时间是一种非常稀缺的资源。

这里有一个简单的解决方案:

  • 创建一个单独的Python脚本,用于定期ping Zendesk API。当新数据到达时,它会将数据放入队列或数据库中
  • 创建一个Django视图,该视图将响应jQuery调用。它将从数据库或队列读取数据,并将其返回到jQuery请求。它实际上不会向Zendesk API本身发出请求

  • 存储新更新的更简单方法是仅为这些数据创建专用模型。创建此模型的一个实例,只要在新数据到达时不断更新其状态(字段值),而不是每次都创建单独的对象。然后,从您的视图中,无论何时收到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'])