【问题标题】:Issue when passing value from template to view through POST request通过 POST 请求将值从模板传递到视图时出现问题
【发布时间】:2016-10-28 13:57:18
【问题描述】:

我正在尝试使用 JQuery 将字段动态添加到 Django 中的表单。我发现了几个类似的问题,但最能解决这个问题的问题是its this one

虽然我理解大部分逻辑,但我无法让它在我的情况下工作。 此外,我不确定他为什么会以某些方式做某事。

我的代码(根据上面的链接)如下所示:

查看

def create_one(request):
    if request.method == 'POST':
        form_empty_layer = UploadEmptyLayerForm(request.POST, extra=request.POST.get('extra_field_count'))

        if form_empty_layer.is_valid():
            print "valid!"
    else:
        form = UploadEmptyLayerForm()
    return render(request, "template", { 'form_empty_layer': form_empty_layer })

表格

class UploadEmptyLayerForm(forms.Form):

    empty_layer_name = forms.CharField(max_length=255, required=True, label="Name of new Layer")

    extra_field_count = forms.CharField(widget=forms.HiddenInput())

    def __init__(self, *args, **kwargs):

        extra_fields = kwargs.pop('extra', 0)
        super(UploadEmptyLayerForm, self).__init__(*args, **kwargs)
        self.fields['extra_field_count'].initial = extra_fields

        for index in range(int(extra_fields)):
            # generate extra fields in the number specified via extra_fields
            self.fields['extra_field_{index}'.format(index=index)] = \
                forms.CharField()

模板

 <form id="empty-layer-uploader" method="post" enctype="multipart/form-data" action="{% url "layer_create" %}">
    <input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
      {% for field in form_empty_layer.visible_fields %}
        {{ field|as_bootstrap }} </br>
      {% endfor %}
      <button type="button" id="add-another">add another</button> </br> </br>
      <button type="submit" id="empty-layer-button" class="btn btn-danger" name="emptylayerbtn">Upload</button>
  </form>

还有 jquery:

form_count = $("[name=extra_field_count");
// get extra form count so we know what index to use for the next item.
$(document.body).on("click", "#add-another",function(e) {
  element = $('<input type="text"/>');
  element.attr('name', 'extra_field_' + form_count);
  $("#empty-layer-uploader").append(element);
  // build element and append it to our forms container

  form_count ++;

  $("[name=extra_field_count]").val(form_count);

  // increment form count so our view knows to populate
  // that many fields for validation
  })

您可能会注意到,我在按钮元素中添加了一个类型属性(类型 = 按钮)。 我也不清楚 jquery 的第一行发生了什么:

form_count = $("[name=extra_field_count");

不应该设置form_count = 0吗?如果没有,那不是缺少']'吗?

尽管如此,当我尝试运行它时,我明白了:

 int() argument must be a string or a number, not 'NoneType'

代码从不获取创建的输入元素的数量。 如果我在视图中手动设置额外变量,那么整个过程就会开始工作:

form_empty_layer = UploadEmptyLayerForm(request.POST, extra=3)

所以我想问题是为什么没有正确地将值从模板传递到视图。

Python 错误

  Traceback (most recent call last):
  File "/home/vagrant/.venvs/geonode/lib/python2.7/site-packages/django/core/handlers/base.py", line 112, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/vagrant/.venvs/geonode/lib/python2.7/site-packages/django/contrib/auth/decorators.py", line 22, in _wrapped_view
return view_func(request, *args, **kwargs)
 File "/home/vagrant/geonode/geonode/layers/views.py", line 885, in layer_create
form_empty_layer = UploadEmptyLayerForm(request.POST, extra=request.POST.get('extra_field_count'))
 File "/home/vagrant/geonode/geonode/layers/forms.py", line 324, in __init__
for index in range(int(extra_fields)):

TypeError: int() 参数必须是字符串或数字,而不是 'NoneType'

编辑

使用@Ian Price 的建议,我解决了我遇到的错误。但是当我尝试从新添加的字段中获取值时,我仍然遇到问题。 通过添加两个新字段并在我的视图中执行:

data = form_empty_layer.cleaned_data
print data

我明白了:

{'empty_layer_name': u'4234', 'extra_field_1': u'', 'extra_field_0': u'', 'extra_field_count': u'5645', 'geom_type': u'POINT'}

所以应用程序的架构确实有问题。键:extra_field_1 和 extra_field_2 应该填充我添加的值。相反,extra_field_count 获得了我添加的两个值中的最新值。

【问题讨论】:

  • 您绝对应该在浏览器控制台中同时收到 JS 错误和终端中的 Python 错误。请分享两者。
  • 谢谢。实际上,我在 Web 开发人员工具中一无所获。我已经提到了我在 python 中遇到的错误。但我已经用完整的错误编辑了这个问题。

标签: jquery django templates views


【解决方案1】:

request.POST.get('extra_field_count') 似乎是该错误的罪魁祸首。由于表单字段extra_field_count 没有额外的字段计数,它没有任何价值。但是,指向 None 值的指针仍然存在,因此可以在表单的 init 方法中找到,即使它的值是 none。

考虑这个例子。

>>> mydict = {'a':None}
>>> print mydict.pop('a')
None

request.POSTkwargs 是字典,就像mydict

最简单的解决方法?检查表单的 __init__ 方法中的空值。

extra_fields = kwargs.pop('extra', 0)
if not extra_fields:
    extra_fields = 0

【讨论】:

  • 谢谢。这修复了错误。但是我仍然无法使我的表单正常工作。它没有通过验证测试 (form.is_valid)。任何想法为什么会发生这种情况?
  • 我想我知道发生了什么。对于我创建的新字段,我已设置它们必须是必需的(required=True)。我认为这是导致错误的原因。设置 required=False 实际上会通过表单验证。但是我仍然需要找到一种方法来从新生成的字段中获取数据。非常感谢任何帮助!
  • 如果我添加两个新字段,我可以在我的视图中以 print(extra_field_count) 的形式访问新添加字段的最后一个值,但是如何访问以前的字段?
猜你喜欢
  • 2021-11-01
  • 2019-01-28
  • 1970-01-01
  • 1970-01-01
  • 2015-07-07
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
  • 2016-11-21
相关资源
最近更新 更多