如何在 Html 中动态显示模型数据?
Posted
技术标签:
【中文标题】如何在 Html 中动态显示模型数据?【英文标题】:How to display a model data dynamically in Html? 【发布时间】:2022-01-20 21:42:45 【问题描述】:我有一个模型,并且在一个函数中这个模型正在更新。 我想动态显示这个模型的数据。因此,应该在不刷新页面的情况下显示新值。我该怎么做?
models.py
class MyLongProcess(models.Model):
active_uuid = models.UUIDField('Active process', null=True, blank=True)
name = models.CharField('Name', max_length=255)
current_step = models.IntegerField('Current step', default=0)
total = models.IntegerField('Total', default=0)
@property
def percentage_sending(self):
# or it can be computed by filtering elements processed in celery with complete status
return int((current_step / total) * 100)
views.py
def setup_wizard(request):
process = MyLongProcess.objects.create(active_uuid=uuid.uuid4(), name=name, total=100)
functions.myClass(..., process=process)
....
return render(request, 'setup_wizard.html', context)
functions.py
class myClass():
def __init__(self, ..., process):
self.download_all(..., process=process)
@app.task(bind=TRUE)
def download_all(self, ..., process):
....
for s in scans:
....
process.current_step += 1
process.save()
...
setup_wizard.html
<div class="progress-bar" role="progressbar"
style="width: my_model_object.percentage_sending %;"
aria-valuenow=" my_model_object.percentage_sending "
aria-valuemin="0" aria-valuemax="100"> my_model_object.percentage_sending %
</div>
我的所有功能都可以正常工作。当我从 Django 管理员查看 MyLongProcess
并刷新页面时,值正在更新。只是我想在前端显示而不刷新。
【问题讨论】:
你考虑过django-channels
吗?设置加载管理页面时要连接的频道,您可以在后端向任何连接的人广播数据。
@Lewis 我以前从未听说过。我会研究它
【参考方案1】:
这不是 Django 的本意。本质上,它呈现静态 HTML 内容,仅此而已。您希望在这样一个耗时的函数中做的是首先呈现一些初始内容(假设进度为 0),然后异步通知前端。这可以通过两种方式完成。第一种方法确实更容易实现,但在资源上稍微难一些——即轮询。本质上,您在 urls.py 中创建了一个特殊的端点,当访问该端点时,它将为您提供您所追求的工作的百分比。那么你可以有一个 javascript 代码,它有 setInterval( (js-code), 1000)
每秒刷新进度。只是给你一个概述如何实现它:
document.addEventListener("DOMContentLoaded", function(event)
var myElement = document.getElementById('my-element');
var task_id = myElement.getAttribute('data-task_id');
setInterval(function()
var progressReq = new XMLHttpRequest();
progressReq.addEventListener("load", function()
myElement.setAttribute('aria-valuenow', this.responseText);
);
progressReq.open("GET", "/progress-query/?task_id=" + task_id);
progressReq.send();
, 1000);
);
在 jQuery 的帮助下,HTTP 请求看起来确实更好,但我只想让您了解一下它的外观。
为了让它工作,你必须修改 html 模板以包含 id,如下所示:
<div ... data-task_id="some-task-id" />
如果您想在此处发布与模型相关的值,请记住对它们进行哈希处理,以免意外发布原始数据库 PK 或类似的东西。
第二种实现起来稍微复杂一些的方法是使用 websockets。这意味着当前端启动时,它会监听通过后端 websocket 实现发送给它的事件。这样,您几乎可以实时更新进度,而不是每秒更新一次。在这两种方法中,javascript 代码都必须访问您要更新的元素——通过var element = document.getElementById( ... )
(这意味着您必须以 id 开头)或借助 jQuery。然后你可以像这样更新值:element.setAttribute('aria-valuenow', 10)
。当然,在 jQuery 等库的帮助下,您的代码看起来会比这更好。
附言一旦进度达到 100,不要忘记(如果你通过轮询方法)打破 setInterval 循环:-)
【讨论】:
以上是关于如何在 Html 中动态显示模型数据?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Express、Mongodb 和 EJ 显示下拉动态数据