Python中Django模板传值给JS时如何处理换行符问题

背景如下:
数据库表 Worker 中有一个 des 字段,其中内容有换行符。

1.前端直接使用<textarea cols="30" rows="10">{{worker.des}}</textarea>的方式显示,换行是正常的。

2.因为涉及 js 处理,需要把{{worker.des}}的值传递给 js 方法,经过处理后再设置到 textarea 中,此时我没有做任何处理,只是做了传值处理,然后重新把内容设置到 textarea 中,换行效果就没了。
例如:document.getElementById('des').innerText='{{worker.des}}';

3.进一步验证,怀疑传值给 js 的时候,换行符因为某种原因被删了,打印两者的长度信息:
{{worker.des|length}} 比 js 代码'{{worker.des}}'.length 的长度多 1

问题:
1.这是什么原因?
2.在 Django 的前端怎么处理这个问题,能让我能在 js 处理后,能在 textarea 中正确显示换行。
3.我想过在后端 view 中把换行符替换成 br,不过这个是最后实在不行的方案吧。


Python中Django模板传值给JS时如何处理换行符问题

5 回复

我找到解决方法了
JS 方法的参数中,带有换行符的话,会有问题,
采用标签中设置自定属性,例如:data_value 的方式放置模板中传来的值,然后在 js 方法中取就可以避免。
但是参数中为嘛不行,我就不知道了。


在Django模板里把带换行符的字符串传给JS,最直接的办法是用json_script模板标签。这玩意儿会把Python对象转成安全的JSON,直接塞到<script>标签里,自动处理换行符这些特殊字符。

比如你有个视图:

def my_view(request):
    context = {
        'my_text': '第一行\n第二行\n第三行'
    }
    return render(request, 'my_template.html', context)

在模板里这么写:

{{ my_text|json_script:"my-data" }}

<script>
    const textData = JSON.parse(document.getElementById('my-data').textContent);
    console.log(textData);  // 输出:第一行\n第二行\n第三行
    // 用的时候可以替换换行符
    const displayText = textData.replace(/\n/g, '<br>');
</script>

json_script生成的是这样的HTML:

<script id="my-data" type="application/json">"第一行\n第二行\n第三行"</script>

这样换行符\n在JSON里会被正确转义,JS解析出来就是带换行符的字符串。如果你要在HTML里显示,再替换成<br>就行。

简单说就是用json_script最省事。

不知道 {{worker.des}} 实际内容是什么,如果里面含有未转义的换行符,那么当执行这一句时
document.getElementById(‘des’).innerText=’{{worker.des}}’;
应该会在浏览器端触发一个非法的多行字符串错误(很奇怪你的实际结果仅仅丢了换行符)

var test = ‘abc
xyz’;
// 这是不合法的

如果提前做了转义( \n )或者用 ES6 的模板字符串(反引号 ``),可以消除这个错误
document.getElementById(‘des’).innerText={{worker.des}};

html 标签中的换行符会被原样保留,这是 #1 可行的可能原因

<textarea cols=“30” rows=“10”>{{worker.des|linebreaks}}</textarea>


document.getElementById(‘des’).innerText=’{{worker.des|escapejs}}’;

模板传数据给 js,用 JSON 序列化一下是常识,不用包任何符号在外面

document.getElementById(‘des’).innerText={{worker.des|jsonify}}

jsonify 并不是 django 内置的 filter,需要自己实现一下,网上随便搜就有

回到顶部