Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django:禁用的下拉列表不';不要把信息发回邮局_Python_Django - Fatal编程技术网

Python Django:禁用的下拉列表不';不要把信息发回邮局

Python Django:禁用的下拉列表不';不要把信息发回邮局,python,django,Python,Django,我在modelform中有一个下拉列表,用户不能更改所选的值。 我发现一个被禁用的确实能满足我的需要。然而,这有一个奇怪之处: 表单第一次打开(获取)时,该值被选中,用户无法更改该值。这很好: 但是,只要不相关字段出现验证错误,POST就会将用户发送回同一表单,以前的信息就会丢失。禁用的foreignkey下拉列表不再包含任何值,非常恼人 我做了一些研究,在stackoverflow上发现了一些东西,似乎当foreignkey下拉小部件被禁用时,根本不会发送回任何数据。而验证可以被重写,以不

我在modelform中有一个下拉列表,用户不能更改所选的值。 我发现一个
被禁用的
确实能满足我的需要。然而,这有一个奇怪之处:

表单第一次打开(获取)时,该值被选中,用户无法更改该值。这很好:

但是,只要
不相关字段出现验证错误,POST就会将用户发送回同一表单,以前的信息就会丢失。禁用的foreignkey下拉列表不再包含任何值,非常恼人

我做了一些研究,在stackoverflow上发现了一些东西,似乎当foreignkey下拉小部件被禁用时,根本不会发送回任何数据。而验证可以被重写,以不为下拉字段抛出任何错误,如所述。但是,如果任何其他不相关的字段抛出错误,则数据将丢失,因为禁用的下拉列表最初从未向POST发送任何数据

这是一个棘手的局面

是否有方法将视图中的数据传递到request.POST?或者你有什么建议?我可以使用
只读
而不是
禁用
,这会起作用,但是下拉列表可以由用户更改,这也很烦人

有什么想法吗?非常感谢

编辑:


小修正:数据没有完全丢失。而是将select错误地设置为初始虚拟值

    <select id="id_form-0-deal_type" name="form-0-deal_type" disabled="disabled">
      <option selected="selected" value="">---------</option>
      <option value="1">deal 1</option>
      <option value="2">deal 2</option>
    </select>
但是它说,
这个QueryDict实例是不可变的

唯一的其他方法是使用常规表单集进行设置。不幸的是,我使用的是modelformset,它适用于现有表单

如果没有其他解决方案,我将开始将模型表单集重构为常规表单集。仍然对想法持开放态度

最终更新+解决方案:

无需将modelformset重构为常规fomset。事实上,我非常不鼓励这样做,因为它本身会带来其他问题。modelformsets为您处理一切,并填充缺少的部分

实际问题是QueryDict是不可变的,但这可以通过复制它们来轻松解决:

formset = deal_formset(request.POST, queryset=formset_query)        
if formset.is_valid():
  pass
else:
  new_post = request.POST.copy()
  deal_types = dict()
  for k,v in new_post.items():
     if k.startswith('hidden'):
        deal_types[k[7:]]= v
  for k,v in deal_types.iteritems():
     new_post[k] = v
  formset = deal_formset(new_post, queryset=formset_query)
这加上弗朗西斯的解决方案:

{{ formset.management_form }}
  {% for fs in formset %}  
     {{ fs.id }} 
     <input type="hidden" name="hidden-{{ fs.prefix }}-deal_type" value="{{fs.deal_type.value}}" />
   {{fs.deal_type}}
{% endfor %}
{% endif %}
{{formset.management_form}
{formset%中的fs为%1}
{{fs.id}
{{fs.deal_type}
{%endfor%}
{%endif%}

只是创造奇迹。。。享受:)

这不是django的东西,而是HTML的东西。禁用的表单元素不会由表单发送

[元素]无法接收用户输入,其值也不会随表单一起提交

&

如果它位于文本/文本区域,则可以使用
只读

您可以做的另一件事是以明文形式显示值,并将其作为隐藏字段提交

{{ form.field_name.label_tag }}
{{ form.field_name.value }}
<input type="hidden" name="field_name" value="{{form.field_name.value}}" />
{{form.field\u name.label\u tag}
{{form.field_name.value}
它不是很优雅,但它可以让你到达那里

您还可以更进一步,编写一些JS来查找禁用的元素,并在后面添加一个带有该元素名称和值的输入

一些JQuery示例:

//Untested, but you get the gist
$(':disabled').each(
    function()
    {
        $(this).after('<input type="hidden" name="' + $(this).attr('name') + '" value="' + $(this).val() + '" />');
    }
);
//未经测试,但您得到了要点
$(':已禁用)。每个(
函数()
{
$(本)。在('')之后;
}
);

我认为这是一个HTML问题,而不是Django问题,禁用的表单字段不会将其值发回,因此会丢失值

如果验证失败,是否可以将值重新绑定到字段?你可以试试类似的东西

if form.is_valid(): # All validation rules pass
    #save form, redirect, etc.
else:
    form.disabled_field = my_value
return render(request, 'contact.html', {'form': form,})

显然,您需要使用模型中的正确数据替换字段名和值。

好的,您可以在模板中使用隐藏属性设置元素,使用视图中的表单集来构建表单:

{{form.field.as_hidden}}

在视图内部,如果问题是数据丢失,则始终可以为适合模型结构的字段设置初始值,因为它是外键。当然,您必须在提交表单之前验证表单,如果表单无效,您可以在必须始终填写的字段中使用初始值来呈现表单。

“数据并没有完全丢失。相反,select被错误地设置为初始伪值。”-即b/c该字段未被过账。因此,默认值为Hanks Francis。很好的解决方案。请看我更新的问题和一些细节。谢谢,我喜欢这个主意。我不理解隐藏的部分,因为我显然失去了默认选择。因此,我需要以某种方式将其发送回视图。我设法做到了这一点,因为弗朗西斯建议增加一个隐藏的输入字段。从那时起,我开始考虑表单集上的首字母缩写请看一下我的最新问题。谢谢:)太好了!我会把这个问题保留在我最喜欢的地方,因为我将来可以处理类似的情况!
{{form.field.as_hidden}}