mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-29 21:14:01 +03:00
fdde44d9d1
It is possible that a key in a MultiValueDict has multiple values, lists are represented this way. When accessing a key in a MultiValueDict it only returns the last element of that key. This becomes a problem when parsing an html dict with a list inside of it. To fix this problem we have to get and set the value using .getlist() and .setlist().
92 lines
2.0 KiB
Python
92 lines
2.0 KiB
Python
"""
|
|
Helpers for dealing with HTML input.
|
|
"""
|
|
import re
|
|
|
|
from django.utils.datastructures import MultiValueDict
|
|
|
|
|
|
def is_html_input(dictionary):
|
|
# MultiDict type datastructures are used to represent HTML form input,
|
|
# which may have more than one value for each key.
|
|
return hasattr(dictionary, 'getlist')
|
|
|
|
|
|
def parse_html_list(dictionary, prefix=''):
|
|
"""
|
|
Used to suport list values in HTML forms.
|
|
Supports lists of primitives and/or dictionaries.
|
|
|
|
* List of primitives.
|
|
|
|
{
|
|
'[0]': 'abc',
|
|
'[1]': 'def',
|
|
'[2]': 'hij'
|
|
}
|
|
-->
|
|
[
|
|
'abc',
|
|
'def',
|
|
'hij'
|
|
]
|
|
|
|
* List of dictionaries.
|
|
|
|
{
|
|
'[0]foo': 'abc',
|
|
'[0]bar': 'def',
|
|
'[1]foo': 'hij',
|
|
'[1]bar': 'klm',
|
|
}
|
|
-->
|
|
[
|
|
{'foo': 'abc', 'bar': 'def'},
|
|
{'foo': 'hij', 'bar': 'klm'}
|
|
]
|
|
"""
|
|
ret = {}
|
|
regex = re.compile(r'^%s\[([0-9]+)\](.*)$' % re.escape(prefix))
|
|
for field, value in dictionary.items():
|
|
match = regex.match(field)
|
|
if not match:
|
|
continue
|
|
index, key = match.groups()
|
|
index = int(index)
|
|
if not key:
|
|
ret[index] = value
|
|
elif isinstance(ret.get(index), dict):
|
|
ret[index][key] = value
|
|
else:
|
|
ret[index] = MultiValueDict({key: [value]})
|
|
return [ret[item] for item in sorted(ret.keys())]
|
|
|
|
|
|
def parse_html_dict(dictionary, prefix=''):
|
|
"""
|
|
Used to support dictionary values in HTML forms.
|
|
|
|
{
|
|
'profile.username': 'example',
|
|
'profile.email': 'example@example.com',
|
|
}
|
|
-->
|
|
{
|
|
'profile': {
|
|
'username': 'example',
|
|
'email': 'example@example.com'
|
|
}
|
|
}
|
|
"""
|
|
ret = MultiValueDict()
|
|
regex = re.compile(r'^%s\.(.+)$' % re.escape(prefix))
|
|
for field in dictionary:
|
|
match = regex.match(field)
|
|
if not match:
|
|
continue
|
|
key = match.groups()[0]
|
|
value = dictionary.getlist(field)
|
|
ret.setlist(key, value)
|
|
|
|
return ret
|