From 3064b83919b3cfff004419b88724dd7852e51679 Mon Sep 17 00:00:00 2001
From: Marcin Nowak <marcin.j.nowak@gmail.com>
Date: Sun, 17 Jul 2016 15:10:13 +0200
Subject: [PATCH] Added possibility to use any MultiValueDict-like objects as a
form data
---
django/forms/widgets.py | 17 ++++++++++-------
tests/forms_tests/tests/test_forms.py | 19 +++++++++++++++++++
2 files changed, 29 insertions(+), 7 deletions(-)
diff --git a/django/forms/widgets.py b/django/forms/widgets.py
index 604a6a4..5c6d6e9 100644
a
|
b
|
from django.conf import settings
|
13 | 13 | from django.forms.utils import flatatt, to_current_timezone |
14 | 14 | from django.templatetags.static import static |
15 | 15 | from django.utils import datetime_safe, formats, six |
16 | | from django.utils.datastructures import MultiValueDict |
17 | 16 | from django.utils.dates import MONTHS |
18 | 17 | from django.utils.deprecation import ( |
19 | 18 | RemovedInDjango20Warning, RenameMethodsBase, |
… |
… |
class MultipleHiddenInput(HiddenInput):
|
331 | 330 | return mark_safe('\n'.join(inputs)) |
332 | 331 | |
333 | 332 | def value_from_datadict(self, data, files, name): |
334 | | if isinstance(data, MultiValueDict): |
335 | | return data.getlist(name) |
336 | | return data.get(name) |
| 333 | try: |
| 334 | getter = data.getlist |
| 335 | except AttributeError: |
| 336 | getter = data.get |
| 337 | return getter(name) |
337 | 338 | |
338 | 339 | |
339 | 340 | class FileInput(Input): |
… |
… |
class SelectMultiple(Select):
|
604 | 605 | return mark_safe('\n'.join(output)) |
605 | 606 | |
606 | 607 | def value_from_datadict(self, data, files, name): |
607 | | if isinstance(data, MultiValueDict): |
608 | | return data.getlist(name) |
609 | | return data.get(name) |
| 608 | try: |
| 609 | getter = data.getlist |
| 610 | except AttributeError: |
| 611 | getter = data.get |
| 612 | return getter(name) |
610 | 613 | |
611 | 614 | |
612 | 615 | @html_safe |
diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py
index 2bd49b7..d626150 100644
a
|
b
|
Java</label></li>
|
855 | 855 | widget=CheckboxSelectMultiple, |
856 | 856 | ) |
857 | 857 | |
| 858 | class MultiValueDictLike(dict): |
| 859 | def getlist(self, key): |
| 860 | return [self[key]] |
| 861 | |
858 | 862 | data = {'name': 'Yesterday', 'composers': ['J', 'P']} |
859 | 863 | f = SongForm(data) |
860 | 864 | self.assertEqual(f.errors, {}) |
… |
… |
Java</label></li>
|
867 | 871 | f = SongForm(data) |
868 | 872 | self.assertEqual(f.errors, {}) |
869 | 873 | |
| 874 | # checking whether MultiValueDictLike.getlist() is called, |
| 875 | # even if composers value is a string |
| 876 | data = MultiValueDictLike(dict(name='Yesterday', composers='J')) |
| 877 | f = SongForm(data) |
| 878 | self.assertEqual(f.errors, {}) |
| 879 | |
870 | 880 | def test_multiple_hidden(self): |
| 881 | class MultiValueDictLike(dict): |
| 882 | def getlist(self, key): |
| 883 | return [self[key]] |
| 884 | |
871 | 885 | class SongForm(Form): |
872 | 886 | name = CharField() |
873 | 887 | composers = MultipleChoiceField( |
… |
… |
Java</label></li>
|
904 | 918 | self.assertEqual(f.cleaned_data['composers'], ['J', 'P']) |
905 | 919 | self.assertEqual(f.cleaned_data['name'], 'Yesterday') |
906 | 920 | |
| 921 | f = SongForm(MultiValueDictLike(dict(name='Yesterday', composers='J')), auto_id=False) |
| 922 | self.assertEqual(f.errors, {}) |
| 923 | self.assertEqual(f.cleaned_data['composers'], ['J']) |
| 924 | self.assertEqual(f.cleaned_data['name'], 'Yesterday') |
| 925 | |
907 | 926 | def test_escaping(self): |
908 | 927 | # Validation errors are HTML-escaped when output as HTML. |
909 | 928 | class EscapingForm(Form): |