html.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. """
  2. Helpers for dealing with HTML input.
  3. """
  4. import re
  5. from django.utils.datastructures import MultiValueDict
  6. def is_html_input(dictionary):
  7. # MultiDict type datastructures are used to represent HTML form input,
  8. # which may have more than one value for each key.
  9. return hasattr(dictionary, 'getlist')
  10. def parse_html_list(dictionary, prefix='', default=None):
  11. """
  12. Used to support list values in HTML forms.
  13. Supports lists of primitives and/or dictionaries.
  14. * List of primitives.
  15. {
  16. '[0]': 'abc',
  17. '[1]': 'def',
  18. '[2]': 'hij'
  19. }
  20. -->
  21. [
  22. 'abc',
  23. 'def',
  24. 'hij'
  25. ]
  26. * List of dictionaries.
  27. {
  28. '[0]foo': 'abc',
  29. '[0]bar': 'def',
  30. '[1]foo': 'hij',
  31. '[1]bar': 'klm',
  32. }
  33. -->
  34. [
  35. {'foo': 'abc', 'bar': 'def'},
  36. {'foo': 'hij', 'bar': 'klm'}
  37. ]
  38. :returns a list of objects, or the value specified in ``default`` if the list is empty
  39. """
  40. ret = {}
  41. regex = re.compile(r'^%s\[([0-9]+)\](.*)$' % re.escape(prefix))
  42. for field, value in dictionary.items():
  43. match = regex.match(field)
  44. if not match:
  45. continue
  46. index, key = match.groups()
  47. index = int(index)
  48. if not key:
  49. ret[index] = value
  50. elif isinstance(ret.get(index), dict):
  51. ret[index][key] = value
  52. else:
  53. ret[index] = MultiValueDict({key: [value]})
  54. # return the items of the ``ret`` dict, sorted by key, or ``default`` if the dict is empty
  55. return [ret[item] for item in sorted(ret)] if ret else default
  56. def parse_html_dict(dictionary, prefix=''):
  57. """
  58. Used to support dictionary values in HTML forms.
  59. {
  60. 'profile.username': 'example',
  61. 'profile.email': 'example@example.com',
  62. }
  63. -->
  64. {
  65. 'profile': {
  66. 'username': 'example',
  67. 'email': 'example@example.com'
  68. }
  69. }
  70. """
  71. ret = MultiValueDict()
  72. regex = re.compile(r'^%s\.(.+)$' % re.escape(prefix))
  73. for field in dictionary:
  74. match = regex.match(field)
  75. if not match:
  76. continue
  77. key = match.groups()[0]
  78. value = dictionary.getlist(field)
  79. ret.setlist(key, value)
  80. return ret