快速摘要:如何确保request.POST中的值顺序正确?
我正在使用HTML表格(使用DataTables进行扩充以隐藏列等,唯一的效果就是隐藏列未包含在“提交”的调用中)并呈现一个每行变形。
在变形does not directly support split forms using the form attribute时,我手动将form=my_desired_unique_id
插入所有相关元素。这适用于<input>
和<textarea>
之类的简单元素,值显示在request.POST.items()
中并且验证正常。
对于变形日期选择器来说,事情有点复杂。 form['datecolumn'].serialize
会生成以下内容: -
<input type="hidden" name="__start__" value="datecolumn:mapping"/>
<input type="date"
name="date"
value="2017-01-01"
id="deformField6" class=" form-control hasDatepicker"/>
<input type="hidden" name="__end__" value="datecolumn:mapping"/>
<script type="text/javascript">
deform.addCallback(
'deformField6',
function deform_cb(oid) {
if (!Modernizr.inputtypes['date'] ||"date" != "date" || window.forceDateTimePolyfill){
$('#' + oid).pickadate({"format": "yyyy-mm-dd", "selectMonths": true, "selectYears": true, "formatSubmit": "yyyy-mm-dd"});
}
}
);
</script>
那里有3个输入(第四个隐藏的输入在添加的HTML中添加了名称&#39; date_submit&#39;)。当用户选择新日期时,可见输入的值不会改变,但新隐藏的日期会发生。在提交时,不知何故将该值传递给主要日期&#39;输入(我没有处理过的一些js)。
结果request.POST.items()
包含日期输入中的这三个元素: -
('__start__', 'datecolumn:mapping')
('date', '2017-02-24')
(这是新选择的日期)('__end__', 'datecolumn:mapping')
我的问题是这些值的顺序不可靠。在同一页面和表单上,多次单击提交将导致request.POST.items()
中的不同值顺序(所有值,而不仅仅是与日期相关的值)。如果结果顺序如上所述,事情就可以了,但如果顺序不同(比如结束是在开始之前,或者日期是在两者之前或之前),那么我会得到一个ValueError引发或验证失败。
我可能首先遍历request.POST.items()
并确保正确的安排,但我想要这种形式的两个日期选择器,我无法知道哪个date
字段属于哪一对{ {1}}和__start__
个标记。
在将POST发送到我的视图代码之前,有没有办法控制POST中元素的顺序?
答案 0 :(得分:0)
我提出的黑客攻击(会接受任何更好的答案!)涉及两个部分。
在我的模板中唯一标记每个日期元素(我将所有日期元素命名为* _date)。
使用模板重新生成相应的POST项目。
具体来说,对于第一步,我使用此函数生成序列化小部件: -
def serialize_with_formid(form, elem_name, formid):
retval = form[elem_name].serialize()
retval = retval.replace('<input type=', '<input form={} type='.format(formid))
retval = retval.replace('<textarea', '<textarea form={}'.format(formid))
if elem_name.endswith('date'): # 'Mark' datepick elements appropriately
retval = retval.replace('name="date"', 'name="{}"'.format(elem_name))
return retval
form
是已创建的表单实例,elem_name
以&#39; date&#39;结尾。对于datepicker元素,formid
对于页面上的每个表单都是唯一的(我的页面中有很多表单)。第2行和第3行在适当的位置插入formid
,if
标记为datepicker元素。
对于第2步,我首先删除__start__
中的所有__end__
和request.POST
元素,然后找到request.POST
中以date
结尾的元素并使用它们将元素追加({正确的顺序)到request.POST
。
def fix_broken_POST(request):
'''
For some reason I'm getting POST elements out of order with retail rendered
form-attribute reliant forms. This reorders the crucial elements (date-related)
so that deform can then do validation etc.
'''
while True:
try: # Assumes same number of both
request.POST.pop('__start__')
request.POST.pop('__end__')
except KeyError as e:
break
list_of_date_keys = [i for i in request.POST.keys() if i.endswith('date')]
list_of_tuples = []
for key in list_of_date_keys:
value = request.POST.pop(key)
list_of_tuples.append(('__start__', '{}:mapping'.format(key)))
list_of_tuples.append(('date', value))
list_of_tuples.append(('__end__', '{}:mapping'.format(key)))
request.POST.extend(list_of_tuples)
再次,这显然是一个黑客/解决方法,所以更多的东西...优雅将不胜感激。