Sending a form array to Flask

后端 未结 3 1825
你的背包
你的背包 2020-12-05 06:41

I have an HTML form with multiple inputs named like this:




        
相关标签:
3条回答
  • 2020-12-05 06:46

    You are following a PHP convention of adding brackets to the field names. It's not a web standard, but because PHP supports it out of the box it is popular; Ruby on Rails also uses it.

    If you do use that convention, to get the POST data on the Flask side you need to include the square brackets in the field name. You can retrieve all values of the list using MultiDict.getlist():

    hello = request.form.getlist('hello[]')
    

    You don't have to use the [] convention at all, of course. Not appending the [] to the hello name will work perfectly fine, at which point you'd use request.form.getlist('hello') in Flask.

    0 讨论(0)
  • 2020-12-05 06:59

    I written a parse function which supports multidimensional dict:php_post=parse_multi_form(request.form)

    def parse_multi_form(form):
        data = {}
        for url_k in form:
            v = form[url_k]
            ks = []
            while url_k:
                if '[' in url_k:
                    k, r = url_k.split('[', 1)
                    ks.append(k)
                    if r[0] == ']':
                        ks.append('')
                    url_k = r.replace(']', '', 1)
                else:
                    ks.append(url_k)
                    break
            sub_data = data
            for i, k in enumerate(ks):
                if k.isdigit():
                    k = int(k)
                if i+1 < len(ks):
                    if not isinstance(sub_data, dict):
                        break
                    if k in sub_data:
                        sub_data = sub_data[k]
                    else:
                        sub_data[k] = {}
                        sub_data = sub_data[k]
                else:
                    if isinstance(sub_data, dict):
                        sub_data[k] = v
    
        return data
    

    Usage:

    >>> request.form={"a[0][name]": "ahui", "a[0][sex]": "female", "a[1][name]": "bhui", "a[1][sex]": "male"}
    >>> parse_multi_form(request.form)
    {'a': {0: {'name': 'ahui', 'sex': 'female'}, 1: {'name': 'bhui', 'sex': 'male'}}}
    

    Warnning: It does not support list,e.g. a[][0]=1&a[][0]=2, it may make programmer to be confused. Either a=[[1,2]] or a[[1],[2]] is too hard to choose.

    So I suggest use dict to replace list:

    <input name="hello[0]" type="text" />
    <input name="hello[1]" type="text" />
    

    If you still want to post complex data, I suggest you use application/json

    0 讨论(0)
  • 2020-12-05 07:11

    I have a form that has arrays with either one or two levels, so either a[1] or b[1][2].

    I've written a regex solution to get this into the dict with posted data.

    import re
    
    re_post = re.compile(r'([a-z_]*)(\[(.*?)\])?(\[(.*?)\])?')
    
    for post_key, post_value in request.form.copy().items():
        matches = list(re_post.findall(post_key)[0][0::2])
    
        if matches[1]:
            request.form.setdefault(matches[0], {})
    
            if matches[2]:
                request.form[matches[0]].setdefault(matches[1], {})
                request.form[matches[0]][matches[1]][matches[2]] = post_value
            else:
                request.form[matches[0]][matches[1]] = post_value
        else:
            continue
        
        del request.form[post_key]
    

    So it iterates over the form keys/values and matches 3 groups in the key: first the 'base' name, and then the names of two levels. If either first or second level name is present, it will create a dictionary and populate it with the posted value and then proceeds to remove the original key/value.

    0 讨论(0)
提交回复
热议问题