开发者

PHP's form bracket trick is to Django's ___?

开发者 https://www.devze.com 2022-12-25 00:38 出处:网络
In PHP you can create form elements with names like: category[1] category[2] or even category[junk] category[test]

In PHP you can create form elements with names like:

category[1]
category[2]

or even

category[junk]
category[test]

When the form is posted, category is automatically turned into a nice dictionary like:

category[1] => "the input value", category[2] => "the other input value"

Is there a way to do that in Django? request.POST.getlist isn't quite right, because it simply returns a list, n开发者_如何学Cot a dictionary. I need the keys too.


You could use django.utils.datastructures.DotExpandedDict with inputs named category.1, category.2 etc. to do something similar, but I don't really see why you would if you ever have to validate and redisplay the information you're receiving, when using a django.forms.Form will do everything for you - appropriate fields will call the getlist method for you and the prefix argument can be used to reuse the same form multiple times.


Hardly pretty, but it should get the job done:

import re

def getdict(d, pref):
  r = re.compile(r'^%s\[(.*)\]$' % pref)
  return dict((r.sub(r'\1', k), v) for (k, v) in d.iteritems() if r.match(k))

D = {
  'foo[bar]': '123',
  'foo[baz]': '456',
  'quux': '789',
}

print getdict(D, 'foo')
# Returns: {'bar': '123', 'baz': '456'}


You can do request.POST['namefromform'] - I take it this isn't what you're looking for?


Use request.POST.keys()


Sorry, as far as I've found, getlist is all there is for what you want, but you could easily parse the request using request.POST.keys() and turn them into dictionaries.


I'm not a python expert but you might try

for key,value in request.POST.iteritems() 
  doSomething....


django.utils.datastrctures has DotExpandedDict

I have written fork of it, that parses dictionary by brackets..

class BrExpandedDict(dict):
    """
    A special dictionary constructor that takes a dictionary in which the keys
    may contain brackets to specify inner dictionaries. It's confusing, but this
    example should make sense.

    >>> d = BrExpandedDict({'person[1][firstname]': ['Simon'], \
            'person[1][lastname]': ['Willison'], \
            'person[2][firstname]': ['Adrian'], \
            'person[2][lastname]': ['Holovaty']})
    >>> d
    {'person': {'1': {'lastname': ['Willison'], 'firstname': ['Simon']}, '2': {'lastname': ['Holovaty'], 'firstname': ['Adrian']}}}
    >>> d['person']
    {'1': {'lastname': ['Willison'], 'firstname': ['Simon']}, '2': {'lastname': ['Holovaty'], 'firstname': ['Adrian']}}
    >>> d['person']['1']
    {'lastname': ['Willison'], 'firstname': ['Simon']}

    """
    def __init__(self, key_to_list_mapping):
        for k, v in key_to_list_mapping.items():
            current = self
            k = k.replace(']', '')
            bits = k.split('[')
            for bit in bits[:-1]:
                current = current.setdefault(bit, {})
            # Now assign value to current position
            try:
                current[bits[-1]] = v
            except TypeError: # Special-case if current isn't a dict.
                current = {bits[-1]: v}

if __name__ == "__main__":
    import doctest
    doctest.testmod()
0

精彩评论

暂无评论...
验证码 换一张
取 消