diff --git a/django/newforms/widgets.py b/django/newforms/widgets.py index a7764b8dc5..274ba01225 100644 --- a/django/newforms/widgets.py +++ b/django/newforms/widgets.py @@ -91,9 +91,22 @@ class Textarea(Widget): return u'%s' % (flatatt(final_attrs), escape(value)) class CheckboxInput(Widget): + def __init__(self, attrs=None, check_test=bool): + # check_test is a callable that takes a value and returns True + # if the checkbox should be checked for that value. + self.attrs = attrs or {} + self.check_test = check_test + def render(self, name, value, attrs=None): final_attrs = self.build_attrs(attrs, type='checkbox', name=name) - if value: final_attrs['checked'] = 'checked' + try: + result = self.check_test(value) + except: # Silently catch exceptions + result = False + if result: + final_attrs['checked'] = 'checked' + if value not in ('', True, False, None): + final_attrs['value'] = smart_unicode(value) # Only add the 'value' attribute if a value is non-empty. return u'' % flatatt(final_attrs) class Select(Widget): @@ -193,19 +206,14 @@ class CheckboxSelectMultiple(SelectMultiple): final_attrs = self.build_attrs(attrs, name=name) output = [u'') return u'\n'.join(output) - def value_from_datadict(self, data, name): - data_list = [k for k, v in self.choices if data.get(name + k)] - return data_list or None - def id_for_label(self, id_): # See the comment for RadioSelect.id_for_label() if id_: diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py index f52635f875..bc38154d74 100644 --- a/tests/regressiontests/forms/tests.py +++ b/tests/regressiontests/forms/tests.py @@ -164,10 +164,18 @@ u'