在Django项目中,借助django-background-tasks,我异步运行了几个重复的后台任务,这些任务持续1-5分钟才能完成。每个任务将对象保存到项目的数据库中,并且网站显示数据库表中的最新数据。显然,我然后希望有一个页面来更新显示的数据,而无需用户每次都手动刷新。我决定使用jQuery提供的Ajax load()
方法执行此操作,因为仅需要重新加载特定的<div>
标签。但是,由于无法估算每个任务需要花费多长时间,因此我暂时将ajax加载请求放置在每10秒执行一次的javascript setInterval()
方法中。但是,这是不必要的重装,因此我想知道是否有更好的方法可以让ajax加载请求仅在完成后台任务并将新对象保存到数据库时执行。
如果可以帮助更好地启发我的处境,这就是我所拥有的:
项目的urls.py文件:
urlpatterns = [
path('', general.views.GeneralView.as_view(), name='general'),
...
path('ajax/status1', alarms1.views.status, name='status1'),
path('ajax/status2', alarms2.views.status, name='status2'),
]
alarms1.tasks.call_alarms(repeat=10, repeat_until=None)
alarms2.tasks.call_alarms(repeat=10, repeat_until=None)
#these calls queue the background tasks
基于类的GeneralView就是这样:
class GeneralView(generic.TemplateView):
template_name = 'general/general.html'
尽管urlpatterns中的其他视图呈现了一个简单的HttpResponse。 因此,模板general.html看起来像这样:
<main>
<div id="content1">
...
</div>
...
<div id="content2">
...
</div>
</main>
...
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script>
setInterval(function() {
$('#content1').html('').load(
'{% url 'status1' %}'
);
$('#content2').html('').load(
'{% url 'status1' %}'
);
}, 10000)
<script>
因此这些应用程序特定的后台任务文件task.py如下所示:
from background_task import background
from .task_script import Alarms # <-- this is the time consuming script
from .models import AlarmSet, Syst
@background(schedule=5)
def call_alarms():
alarm=Alarms() # <-- time consuming task being executed
'''updating the database'''
als=AlarmSet()
als.save()
for warning in alarm.warnings:
als.syst_set.create(name=warning.system_name,
... everything else ...
time=warning.record_time)
print("Alarms updated")
该方法的结尾是我只希望ajax加载发生的地方。