2017-02-23 24 views
0

快速概要:如何确保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个输入有(和第四隐藏一个获取名为“date_submit”渲染HTML添加)。当用户选择一个新的日期时,可见输入的值不会改变,但是新的隐藏的输入的值会改变。在提交时,不知何故该值被传递给主'日期'输入(有些js我没有处理)。

产生的request.POST.items()包含从数据输入这三个要素: -

  1. ('__start__', 'datecolumn:mapping')
  2. ('date', '2017-02-24')(这是新选择的日期)
  3. ('__end__', 'datecolumn:mapping')

我的问题在这里这些值的顺序是不可靠的。在同一页面和表单上,单击多次提交将导致request.POST.items()(所有值,而不仅仅是与日期有关的值)的不同顺序值。如果结果顺序如上所述,事情工作正常,但如果顺序不同(比如说结束是在开始之前,或者日期在两者之前或之后),那么我会得到一个ValueError引发或验证失败。

我可能通过request.POST.items()第一迭代,并确保正确的安排,但我想在此形成两个日期选择器,我也没有办法知道哪些date领域属于哪个对__start____end__标记。

是否有任何方法来控制一个POST中的元素的顺序,然后它被发送到我的视图代码?

回答

0

我提出的破解(接受任何更好的答案,这!)涉及两部分。

  1. 在我的模板中唯一标记每个日期元素(我将所有日期元素命名为* _date)。

  2. 使用该模板重新生成相应的POST项目。

具体而言,步骤一个I产生在使用该功能的序列化小窗口: -

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与日期选择器元件“日期”结束,并且formid是网页上的每个表单都是唯一的(我的网页上有很多表单)。第2行和第3行在适当的地方插入formid,并且if标记datepicker元素。

对于步骤2 I首先从request.POST删除所有__start____end__元素,则找到request.POSTdate结束,并使用它们来附加(以正确的顺序)元素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) 

同样,这显然是一个黑客/解决方法,所以更多的东西......优雅,将不胜感激。