Django如何将模型数据传递到模板JavaScript中并正确渲染字段值
Django模板传递QuerySet到JavaScript并读取字段的解决方案
问题根源
- Django模板中直接输出QuerySet或模型对象时,默认会调用其
__str__方法,输出的是<QuerySet [<ChatStream object (id)>]>这类对象标识,而非实际字段内容 chat是QuerySet集合对象,不是单个模型实例,直接{{ chat.user }}无法读取到字段属性- 未执行求值的QuerySet不支持负索引操作,所以直接用
last过滤器会报错 - 原有JS代码存在语法错误:变量定义后多了冗余闭合大括号、定时器调用的函数名与实际定义的函数名不一致
可行解决方案
方案1:后端提前序列化(推荐,适合绝大多数场景)
直接在视图层把需要传递的数据序列化为JSON格式,前端JS可以直接解析为原生对象使用,避免模板渲染的各种问题。
修改views.py代码:
import json from django.core.serializers.json import DjangoJSONEncoder from django.utils.safestring import mark_safe def displayDict(request): m = ChatStream.objects.filter(name = visitor_ip_address(request)) last = m.latest('name') # 序列化所有聊天数据,可按需指定返回的字段 chat_data = list(m.values('user', 'bot', 'created_date')) chat_json = mark_safe(json.dumps(chat_data, cls=DjangoJSONEncoder)) # 序列化最新一条数据 last_data = { 'user': last.user, 'bot': last.bot, 'created_date': last.created_date } last_json = mark_safe(json.dumps(last_data, cls=DjangoJSONEncoder)) return render(request, 'chatStream.html', {"chat": chat_json, "last": last_json})
修改模板JS代码:
<p id="demo2">I will display when two seconds have passed.</p> <script> // 不需要加引号,直接解析为JS数组/对象 var data = {{ chat }}; var lastEntry = {{ last }}; setTimeout(myTimeout2, 2000) function myTimeout2() { // 可直接读取字段属性,也可遍历data数组获取所有记录 document.getElementById("demo2").innerHTML = "2秒后结果:用户输入:" + lastEntry.user + ",机器人回复:" + lastEntry.bot; } </script>
方案2:模板层遍历渲染(适合小数据量、简单场景)
如果不想修改后端代码,可以在模板中直接遍历QuerySet读取字段:
<p id="demo2">I will display when two seconds have passed.</p> <script> // 遍历所有聊天记录拼接用户输入内容 var allUserContent = "{% for item in chat %}{{ item.user }}、{% endfor %}"; var lastUser = "{{ last.user }}"; setTimeout(myTimeout2, 2000) function myTimeout2() { document.getElementById("demo2").innerHTML = "2 seconds " + allUserContent + " 最新用户输入:" + lastUser; } </script>
内容的提问来源于stack exchange,提问作者Katie Melosto
相关产品推荐
相关产品推荐

