Django表单-验证错误后重新加载时变量类型发生变化 [英] Django form - type of variable changes when reloaded after validation error
问题描述
我已经花了一些时间,但是无法弄清楚以下行为的确切原因。
I have spent some time on this but cannot figure out the exact cause of the following behaviour.
我有一个Django表单,并且在模板中我试图查看列表中是否存在整数,然后对其进行处理。
I have a Django form and in the template I am trying to see if an integer is present in a list and then doing something with it.
{% if pk in form.area.value %} {# form.area.value is a list like [7,21] #}
do something
{% endif%}
一切正常,除非在验证错误后重新加载表单。在这种情况下,我要比较的列表会自动转换为字符串列表(来自整数列表),并且 if
测试失败。因此,上方的 [7,21]
变为 ['7','21']
Everything works fine except in cases where the form is reloaded after a validation error. In such cases, the list that I am comparing with, gets converted to list of strings (from a list of ints) on its own and the if
test fails. So [7,21]
above becomes ['7','21']
如果有帮助,这是在视图中呈现表单的方式:
In case it helps, this is how the form is being rendered in the view:
在GET请求上(如果if条件起作用的话)罚款):
On the GET request (where the if condition works fine):
form = SchoolForm(instance = school)
return render(request, 'edit-school.html', {'form': form, 'school_id': school_id})
在POST请求之后(如果条件在模板中失败):
After the POST request (where the if condition fails in the template):
form = SchoolForm(request.POST or None, instance=school, request=request)
return render(request, 'edit-school.html', {'form': form, 'school_id': school_id})
更新:通过在表单中的POST请求后通过声明表单中的另一种方法将字符串值转换回int来使其工作(如@bruno(在下面的答案中)并在模板中使用它。以下是代码段(有关其在模板中的使用方式):
Update: Got it to work by converting string values after the POST request in the form back to int by declaring another method in the form (as suggested by @bruno in the answer below) and using it in the template. Here's the code snippet (of how its being used in the template):
<div class="checkbox">
{% for pk, choice in form.area.field.widget.choices %}
<label for="id_{{sub_type}}_{{form.area.name}}_{{ forloop.counter0 }}">
<input class="form-control" id="id_{{sub_type}}_{{form.area.name}}_{{ forloop.counter0 }}" name="{{form.area.name}}" type="checkbox" value="{{ pk }}" {% if pk in form.area_values %} checked="checked" {% endif %}/>
<span class="badge">{{ choice }}</span>
</label>
{% endfor %}
</div>
推荐答案
用户提交表单后, {{form.area.value}}
(在Python中解析为 form [ area]。value
))来自 request.POST
的原始数据,它们的确是字符串。
After the user submitted the form, {{ form.area.value }}
(which in Python resolves to form["area"].value
) is populated with the raw data from request.POST
, which are indeed strings.
您没有在模板中清楚地说明您要尝试哪种奇特的东西,因此很难为您提供最佳解决方案用例,但作为一般规则,模板并不是什么花哨的地方-而是Python的目的(在您的视图中,在表单中,在自定义templatetag或过滤器中)。
You didn't clearly explain what kind of "fancy thing" you're trying to do in the template so it's hard to come with a "best" solution for your use case, but as a general rule, templates are not the place for anything fancy - that's what Python is for (either in your view, in your form, in a custom templatetag or filter etc).
一种非常快速,简单的解决方案是在表单中添加一个方法,该方法将 area
边界域值返回为整数:
A very quick and simple solution would be to add a method to your form that returns the area
boundfield values as ints:
class SchoolForm(forms.ModelForm):
# your code here
def area_values(self):
# XXX this might require some conditionals or
# error handling to be failsafe
# works with both python 2.x and 3.x
return [int(v) for v in self["area"].value()]
然后在模板中,替换 {%,如果pk形式为form.area.value%}
,其中 {%,如果pk形式为form.area_values%}
then in your template, replace {% if pk in form.area.value %}
with {% if pk in form.area_values %}
这篇关于Django表单-验证错误后重新加载时变量类型发生变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!