Django表单-验证错误后重新加载时变量类型发生变化 [英] Django form - type of variable changes when reloaded after validation error

查看:46
本文介绍了Django表单-验证错误后重新加载时变量类型发生变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经花了一些时间,但是无法弄清楚以下行为的确切原因。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆