Django: 禁用下拉菜单无法将信息发送回POST

29 浏览
0 Comments

Django: 禁用下拉菜单无法将信息发送回POST

我有一个模型表单中的下拉菜单,用户不应该能够更改所选的值。我发现 disabled 语句确实可以做到我需要的事情。但是有一个奇怪的问题:

第一次打开表单(GET)时,值已被选择,用户不能更改值。这是很好的:

\"enter

但是,一旦存在与 不相关的字段 相关的验证错误并且 POST 将用户返回到相同的表单,先前的信息将丢失。已禁用的外键下拉菜单不再包含任何值,这非常令人烦恼。

\"enter

我进行了一些研究,发现了stackoverflow上的一些内容,似乎当外键下拉菜单小部件被禁用时,根本不会返回任何数据。虽然验证可以被重写以不对下拉字段抛出任何错误,正如这里的第三个答案所解释的那样。但是如果任何其他不相关的字段抛出错误,则数据将丢失,因为第一次已禁用的下拉菜单根本没有发送任何数据到POST。

这是一个棘手的情况。

有没有一种方法可以将数据传递到请求.POST中的视图中?或者您有什么建议?我可以使用 readonly 而不是 disabled,这将起作用,但是用户仍然可以更改下拉菜单,这也很烦人。

有什么想法吗?非常感谢

编辑:

小修正:数据并没有完全丢失。相反,选择是错误地设置为初始虚拟值。


更新:

Francis的解决方案看起来非常有前途。因此,我尝试了他的第二个建议并在html中添加了一个隐藏的输入字段,并将正确的值传递到POST中。

问题现在是如何继续。我尝试添加表单集的表单查询字典中缺失的条目(以便设置正确的下拉列表值):

formset.forms[0].data['form-0-deal_type'] = formset.forms[0].data['form-0-hiddenfield'] 

但它说此QueryDict实例不可变

唯一 的其他解决办法就是通过表单集的初始值进行设置。可的确实现我正在使用modelformsets,它对现有表单不支持初始值。

如果没有其他解决方案,我将开始将我的modelformset转换为正常的表单集。但还是希望有其他的解决方案。

最终更新+解决方案:

没有必要将modelformset重构为常规表单集。事实上,我强烈不建议这样做,因为这会带来其他问题。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)

加上Francis的解决方案:

{{ formset.management_form }}
  {% for fs in formset %}  
     {{ fs.id }} 
     
   {{fs.deal_type}}
{% endfor %}
{% endif %}

真的可以创造奇迹...享受吧 🙂

admin 更改状态以发布 2023年5月20日
0
0 Comments

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

{{form.field.as_hidden}}

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

0
0 Comments

这不是一个Django的问题,而是一个HTML的问题。禁用的表单元素不会被表单发送。

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

http://www.w3.org/TR/html401/interact/forms.html#h-17.12.1http://www.w3schools.com/tags/att_input_disabled.asp

如果是文本框/文本区域,你可以使用 readonly
http://www.w3schools.com/tags/att_input_readonly.asp

还有一种方法,可以将值以明文显示,并将其提交为隐藏字段.....

{{ form.field_name.label_tag }}
{{ form.field_name.value }}

这并不是很优雅,但可以解决你的问题。

你还可以进一步编写一些JS代码,查找禁用的元素,并在后面添加该元素的名称和值的输入。

一些样例JQuery:

//Untested, but you get the gist
$(':disabled').each(
    function()
    {
        $(this).after('');
    }
);

0