如何在 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 显示下拉动态数据

如何在 Spark List 中正确显示动态大小的项目?

如何使用 Django 模型在网页上获取动态数据?

在使用 tinker CLI 时,Laravel 如何在 Eloquent 模型上查找和显示动态属性?

在 Django 中以 html 模式加载动态数据

如何将一个对象数组中的所有项目从Javascript动态显示为HTML?