尝试将 Django 表单字段呈现为 html 模板中脚本标记中的变量,但 javascript 不起作用
Trying to render a django form field as a variable in a script tag in an html template, but the javascript isn't working
我的问题很简单——我正在尝试将 django 表单中的表单字段渲染到 javascript 变量中,该变量在 django 模板中的 <script>
标记内定义。
当我输出一个CharField时,没有问题。但是,当我尝试呈现 ChoiceField 时,生成的输出会破坏 html,并阻止脚本标签正确解析我的变量。
为了演示我的设置,我在 forms.py 中定义了一个表单,与这个示例表单完全一样:
from django import forms
form = TestForm(forms.Form):
testfield = forms.ChoiceField(initial="increase_rate",
choices=[
("a", "option a"),
("b", "option b"),
("c", "option c"),
("d", "option d")
])
我正在 views.py 中实例化表单,并将其传递到要呈现的 django 模板中。
from django.shortcuts import render
from .forms import TestForm
[...]
@require_http_methods(["GET"])
def webpage(request):
form = TestForm()
return render(request, 'index.html', {"form":form})
然后,最后,在我的模板中,我有如下内容:
[...]
<script>
window.testfield = '{{ form.testfield }}'
</script>
[...]
到目前为止,一切正常。一点也不麻烦。但是当我将字段渲染到模板中并在我的浏览器中检查它时,我得到以下信息:
<script>
window.testfield = '<select name="trigger" id="id_trigger">
<option value="a" selected>option a</option>
<option value="b">option b</option>
<option value="c">option c</option>
<option value="d">option d</option>
</select>'
</script>
此输出打破了 html,并防止脚本标记被解释为我想要的变量。这是一个主要问题,因为我想在页面的其他地方以编程方式重用这些。
我尝试了以下方法:
<script>
window.testfield = '{{ form.testfield|escape }}'
</script>
但是还是没有成功。任何人都可以提供任何帮助,我们将不胜感激!
我正在积极研究解决方案。我目前的猜测是输出需要以某种我不理解的方式转义。我想模板标签和过滤器有我的答案,我只需要找到它。一旦找到解决方案,将post更新。
使用<script type="text/template"></script>
。
这样浏览器就知道它只是文本并会忽略它。
所以,我想通了。事实证明,问题是在 HTML.
解析标签时,白色 space、换行符和未转义的双引号 (") 的存在破坏了标签
所以我最终使用了以下内容:
{% spaceless %}
<script>
window.testfield = '{{ form.testfield|addslashes }}'
</script>
{% endspaceless %}
它起作用了,允许我将 django 表单字段的字符串表示形式存储在 javascript 变量中。根据文档,{% spaceless %}“删除 HTML 标签之间的白色 space。这包括制表符和换行符。” [1].至于过滤器 |addslashes,它“在引号前添加斜线。对于转义 CSV 中的字符串很有用”[2]。在我的例子中,这两种解决方案都是必需的,因为没有它们,脚本标签就坏了。
至于为什么 |escape 过滤器不能单独工作,我不确定。阅读文档,似乎应该有。以下是 |escape 过滤器实际执行的操作 [3]:
Escapes a string’s HTML. Specifically, it makes these replacements:
< is converted to <
> is converted to >
' (single quote) is converted to '
" (double quote) is converted to "
& is converted to &
我只能猜测为什么这不起作用。我认为这是因为它对白色 space 没有任何作用。但我不应该推测。我欢迎您提出任何解释。一如既往,理解机器的思维方式比任何单一的、特定的解决方案都要好。谢谢。
[1] - https://docs.djangoproject.com/en/dev/ref/templates/builtins/#spaceless
[2] - https://docs.djangoproject.com/en/dev/ref/templates/builtins/#addslashes
[3] - https://docs.djangoproject.com/en/dev/ref/templates/builtins/#escape
我的问题很简单——我正在尝试将 django 表单中的表单字段渲染到 javascript 变量中,该变量在 django 模板中的 <script>
标记内定义。
当我输出一个CharField时,没有问题。但是,当我尝试呈现 ChoiceField 时,生成的输出会破坏 html,并阻止脚本标签正确解析我的变量。
为了演示我的设置,我在 forms.py 中定义了一个表单,与这个示例表单完全一样:
from django import forms
form = TestForm(forms.Form):
testfield = forms.ChoiceField(initial="increase_rate",
choices=[
("a", "option a"),
("b", "option b"),
("c", "option c"),
("d", "option d")
])
我正在 views.py 中实例化表单,并将其传递到要呈现的 django 模板中。
from django.shortcuts import render
from .forms import TestForm
[...]
@require_http_methods(["GET"])
def webpage(request):
form = TestForm()
return render(request, 'index.html', {"form":form})
然后,最后,在我的模板中,我有如下内容:
[...]
<script>
window.testfield = '{{ form.testfield }}'
</script>
[...]
到目前为止,一切正常。一点也不麻烦。但是当我将字段渲染到模板中并在我的浏览器中检查它时,我得到以下信息:
<script>
window.testfield = '<select name="trigger" id="id_trigger">
<option value="a" selected>option a</option>
<option value="b">option b</option>
<option value="c">option c</option>
<option value="d">option d</option>
</select>'
</script>
此输出打破了 html,并防止脚本标记被解释为我想要的变量。这是一个主要问题,因为我想在页面的其他地方以编程方式重用这些。
我尝试了以下方法:
<script>
window.testfield = '{{ form.testfield|escape }}'
</script>
但是还是没有成功。任何人都可以提供任何帮助,我们将不胜感激!
我正在积极研究解决方案。我目前的猜测是输出需要以某种我不理解的方式转义。我想模板标签和过滤器有我的答案,我只需要找到它。一旦找到解决方案,将post更新。
使用<script type="text/template"></script>
。
这样浏览器就知道它只是文本并会忽略它。
所以,我想通了。事实证明,问题是在 HTML.
解析标签时,白色 space、换行符和未转义的双引号 (") 的存在破坏了标签所以我最终使用了以下内容:
{% spaceless %}
<script>
window.testfield = '{{ form.testfield|addslashes }}'
</script>
{% endspaceless %}
它起作用了,允许我将 django 表单字段的字符串表示形式存储在 javascript 变量中。根据文档,{% spaceless %}“删除 HTML 标签之间的白色 space。这包括制表符和换行符。” [1].至于过滤器 |addslashes,它“在引号前添加斜线。对于转义 CSV 中的字符串很有用”[2]。在我的例子中,这两种解决方案都是必需的,因为没有它们,脚本标签就坏了。
至于为什么 |escape 过滤器不能单独工作,我不确定。阅读文档,似乎应该有。以下是 |escape 过滤器实际执行的操作 [3]:
Escapes a string’s HTML. Specifically, it makes these replacements:
< is converted to <
> is converted to >
' (single quote) is converted to '
" (double quote) is converted to "
& is converted to &
我只能猜测为什么这不起作用。我认为这是因为它对白色 space 没有任何作用。但我不应该推测。我欢迎您提出任何解释。一如既往,理解机器的思维方式比任何单一的、特定的解决方案都要好。谢谢。
[1] - https://docs.djangoproject.com/en/dev/ref/templates/builtins/#spaceless
[2] - https://docs.djangoproject.com/en/dev/ref/templates/builtins/#addslashes
[3] - https://docs.djangoproject.com/en/dev/ref/templates/builtins/#escape