Ticket #7568: 0001-started-to-move-newforms-closer-to-pep8-standards.diff

File 0001-started-to-move-newforms-closer-to-pep8-standards.diff, 30.2 KB (added by Steve Milner, 16 years ago)
  • django/newforms/extras/widgets.py

    diff --git a/django/newforms/extras/widgets.py b/django/newforms/extras/widgets.py
    index e3ef1d7..bd6220d 100644
    a b from django.newforms.widgets import Widget, Select  
    99from django.utils.dates import MONTHS
    1010from django.utils.safestring import mark_safe
    1111
    12 __all__ = ('SelectDateWidget',)
     12__all__ = ('SelectDateWidget', )
    1313
    1414RE_DATE = re.compile(r'(\d{4})-(\d\d?)-(\d\d?)$')
    1515
     16
    1617class SelectDateWidget(Widget):
    1718    """
    1819    A Widget that splits date input into three <select> boxes.
    class SelectDateWidget(Widget):  
    2526    year_field = '%s_year'
    2627
    2728    def __init__(self, attrs=None, years=None):
    28         # years is an optional list/tuple of years to use in the "year" select box.
     29        # years is an optional list/tuple of years to use in the
     30        # "year" select box.
    2931        self.attrs = attrs or {}
    3032        if years:
    3133            self.years = years
    class SelectDateWidget(Widget):  
    4143            if isinstance(value, basestring):
    4244                match = RE_DATE.match(value)
    4345                if match:
    44                     year_val, month_val, day_val = [int(v) for v in match.groups()]
     46                    year_val, month_val, day_val = [
     47                           int(v) for v in match.groups()]
    4548
    4649        output = []
    4750
    class SelectDateWidget(Widget):  
    5356        month_choices = MONTHS.items()
    5457        month_choices.sort()
    5558        local_attrs = self.build_attrs(id=self.month_field % id_)
    56         select_html = Select(choices=month_choices).render(self.month_field % name, month_val, local_attrs)
     59        select_html = Select(choices=month_choices).render(
     60               self.month_field % name, month_val, local_attrs)
    5761        output.append(select_html)
    5862
    5963        day_choices = [(i, i) for i in range(1, 32)]
    6064        local_attrs['id'] = self.day_field % id_
    61         select_html = Select(choices=day_choices).render(self.day_field % name, day_val, local_attrs)
     65        select_html = Select(choices=day_choices).render(
     66               self.day_field % name, day_val, local_attrs)
    6267        output.append(select_html)
    6368
    6469        year_choices = [(i, i) for i in self.years]
    6570        local_attrs['id'] = self.year_field % id_
    66         select_html = Select(choices=year_choices).render(self.year_field % name, year_val, local_attrs)
     71        select_html = Select(choices=year_choices).render(
     72               self.year_field % name, year_val, local_attrs)
    6773        output.append(select_html)
    6874
    6975        return mark_safe(u'\n'.join(output))
    class SelectDateWidget(Widget):  
    7379    id_for_label = classmethod(id_for_label)
    7480
    7581    def value_from_datadict(self, data, files, name):
    76         y, m, d = data.get(self.year_field % name), data.get(self.month_field % name), data.get(self.day_field % name)
     82        y = data.get(self.year_field % name)
     83        m = data.get(self.month_field % name)
     84        d = data.get(self.day_field % name)
    7785        if y and m and d:
    7886            return '%s-%s-%s' % (y, m, d)
    7987        return data.get(name, None)
  • django/newforms/fields.py

    diff --git a/django/newforms/fields.py b/django/newforms/fields.py
    index dfe46a2..6d74c74 100644
    a b from django.utils.translation import ugettext_lazy as _  
    2121from django.utils.encoding import StrAndUnicode, smart_unicode, smart_str
    2222
    2323from util import ErrorList, ValidationError
    24 from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, DateTimeInput
     24from widgets import TextInput, PasswordInput, HiddenInput
     25from widgets import MultipleHiddenInput, FileInput, CheckboxInput, Select
     26from widgets import NullBooleanSelect, SelectMultiple, DateTimeInput
    2527
    2628
    2729__all__ = (
    EMPTY_VALUES = (None, '')  
    4042
    4143
    4244class Field(object):
    43     widget = TextInput # Default widget to use when rendering this type of Field.
    44     hidden_widget = HiddenInput # Default widget to use when rendering this as "hidden".
     45    # Default widget to use when rendering this type of Field.
     46    widget = TextInput
     47    # Default widget to use when rendering this as "hidden".
     48    hidden_widget = HiddenInput
    4549    default_error_messages = {
    4650        'required': _(u'This field is required.'),
    4751        'invalid': _(u'Enter a valid value.'),
    class Field(object):  
    119123        result.widget = copy.deepcopy(self.widget, memo)
    120124        return result
    121125
     126
    122127class CharField(Field):
    123128    default_error_messages = {
    124129        'max_length': _(u'Ensure this value has at most %(max)d characters (it has %(length)d).'),
  • django/newforms/forms.py

    diff --git a/django/newforms/forms.py b/django/newforms/forms.py
    index 2c481e4..163a2c2 100644
    a b __all__ = ('BaseForm', 'Form')  
    1717
    1818NON_FIELD_ERRORS = '__all__'
    1919
     20
    2021def pretty_name(name):
    2122    "Converts 'first_name' to 'First name'"
    2223    name = name[0].upper() + name[1:]
    2324    return name.replace('_', ' ')
    2425
     26
    2527def get_declared_fields(bases, attrs, with_base_fields=True):
    2628    """
    2729    Create a list of form field instances from the passed in 'attrs', plus any
    def get_declared_fields(bases, attrs, with_base_fields=True):  
    3234    Otherwise, only fields in the 'declared_fields' attribute on the bases are
    3335    used. The distinction is useful in ModelForm subclassing.
    3436    """
    35     fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if isinstance(obj, Field)]
     37    fields = [(field_name, attrs.pop(field_name)) \
     38              for field_name, obj in attrs.items() if isinstance(obj, Field)]
    3639    fields.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter))
    3740
    3841    # If this class is subclassing another Form, add that Form's fields.
    def get_declared_fields(bases, attrs, with_base_fields=True):  
    4952
    5053    return SortedDict(fields)
    5154
     55
    5256class DeclarativeFieldsMetaclass(type):
    5357    """
    5458    Metaclass that converts Field attributes to a dictionary called
    5559    'base_fields', taking into account parent class 'base_fields' as well.
    5660    """
     61
    5762    def __new__(cls, name, bases, attrs):
    5863        attrs['base_fields'] = get_declared_fields(bases, attrs)
    5964        return type.__new__(cls, name, bases, attrs)
    6065
     66
    6167class BaseForm(StrAndUnicode):
    62     # This is the main implementation of all the Form logic. Note that this
    63     # class is different than Form. See the comments by the Form class for more
    64     # information. Any improvements to the form API should be made to *this*
    65     # class, not to the Form class.
     68    """
     69    This is the main implementation of all the Form logic. Note that this
     70    class is different than Form. See the comments by the Form class for more
     71    information. Any improvements to the form API should be made to *this*
     72    class, not to the Form class.
     73    """
     74
    6675    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
    6776                 initial=None, error_class=ErrorList, label_suffix=':'):
    6877        self.is_bound = data is not None or files is not None
    class BaseForm(StrAndUnicode):  
    118127
    119128        Subclasses may wish to override.
    120129        """
    121         return self.prefix and ('%s-%s' % (self.prefix, field_name)) or field_name
     130        return self.prefix and ('%s-%s' % (self.prefix, field_name)) or \
     131                               field_name
    122132
    123     def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row):
    124         "Helper function for outputting HTML. Used by as_table(), as_ul(), as_p()."
    125         top_errors = self.non_field_errors() # Errors that should be displayed above all fields.
     133    def _html_output(self, normal_row, error_row, row_ender,
     134                           help_text_html, errors_on_separate_row):
     135        """
     136        Helper function for outputting HTML. Used by as_table(),
     137        as_ul(), as_p().
     138        """
     139        # Errors that should be displayed above all fields.
     140        top_errors = self.non_field_errors()
    126141        output, hidden_fields = [], []
    127142        for name, field in self.fields.items():
    128143            bf = BoundField(self, field, name)
    129             bf_errors = self.error_class([escape(error) for error in bf.errors]) # Escape and cache in local variable.
     144            # Escape and cache in local variable.
     145            bf_errors = self.error_class([escape(error) \
     146                        for error in bf.errors])
    130147            if bf.is_hidden:
    131148                if bf_errors:
    132                     top_errors.extend([u'(Hidden field %s) %s' % (name, force_unicode(e)) for e in bf_errors])
     149                    top_errors.extend([u'(Hidden field %s) %s' % (
     150                           name, force_unicode(e)) for e in bf_errors])
    133151                hidden_fields.append(unicode(bf))
    134152            else:
    135153                if errors_on_separate_row and bf_errors:
    class BaseForm(StrAndUnicode):  
    148166                    help_text = help_text_html % force_unicode(field.help_text)
    149167                else:
    150168                    help_text = u''
    151                 output.append(normal_row % {'errors': force_unicode(bf_errors), 'label': force_unicode(label), 'field': unicode(bf), 'help_text': help_text})
     169                output.append(normal_row % {
     170                           'errors': force_unicode(bf_errors),
     171                           'label': force_unicode(label),
     172                           'field': unicode(bf),
     173                           'help_text': help_text})
    152174        if top_errors:
    153175            output.insert(0, error_row % force_unicode(top_errors))
    154176        if hidden_fields: # Insert any hidden fields in the last row.
    class BaseForm(StrAndUnicode):  
    157179                last_row = output[-1]
    158180                # Chop off the trailing row_ender (e.g. '</td></tr>') and
    159181                # insert the hidden fields.
    160                 output[-1] = last_row[:-len(row_ender)] + str_hidden + row_ender
     182                output[-1] = last_row[:-len(row_ender)] + str_hidden + \
     183                               row_ender
    161184            else:
    162185                # If there aren't any rows in the output, just append the
    163186                # hidden fields.
    class BaseForm(StrAndUnicode):  
    165188        return mark_safe(u'\n'.join(output))
    166189
    167190    def as_table(self):
    168         "Returns this form rendered as HTML <tr>s -- excluding the <table></table>."
    169         return self._html_output(u'<tr><th>%(label)s</th><td>%(errors)s%(field)s%(help_text)s</td></tr>', u'<tr><td colspan="2">%s</td></tr>', '</td></tr>', u'<br />%s', False)
     191        """
     192        Returns this form rendered as HTML <tr>s -- excluding the
     193        <table></table>.
     194        """
     195        return self._html_output(
     196            u'<tr><th>%(label)s</th><td>%(errors)s%(field)s%(help_text)s\
     197</td></tr>',
     198            u'<tr><td colspan="2">%s</td></tr>',
     199            '</td></tr>',
     200            u'<br />%s',
     201            False)
    170202
    171203    def as_ul(self):
    172204        "Returns this form rendered as HTML <li>s -- excluding the <ul></ul>."
    173         return self._html_output(u'<li>%(errors)s%(label)s %(field)s%(help_text)s</li>', u'<li>%s</li>', '</li>', u' %s', False)
     205        return self._html_output(
     206            u'<li>%(errors)s%(label)s %(field)s%(help_text)s</li>',
     207            u'<li>%s</li>',
     208            '</li>',
     209            u' %s',
     210            False)
    174211
    175212    def as_p(self):
    176213        "Returns this form rendered as HTML <p>s."
    177         return self._html_output(u'<p>%(label)s %(field)s%(help_text)s</p>', u'%s', '</p>', u' %s', True)
     214        return self._html_output(
     215            u'<p>%(label)s %(field)s%(help_text)s</p>',
     216            u'%s',
     217            '</p>',
     218            u' %s',
     219            True)
    178220
    179221    def non_field_errors(self):
    180222        """
    class BaseForm(StrAndUnicode):  
    197239            # value_from_datadict() gets the data from the data dictionaries.
    198240            # Each widget type knows how to retrieve its own data, because some
    199241            # widgets split data over several HTML fields.
    200             value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
     242            value = field.widget.value_from_datadict(self.data,
     243                           self.files, self.add_prefix(name))
    201244            try:
    202245                if isinstance(field, FileField):
    203246                    initial = self.initial.get(name, field.initial)
    class BaseForm(StrAndUnicode):  
    238281                return True
    239282        return False
    240283
     284
    241285class Form(BaseForm):
    242286    "A collection of Fields, plus their associated data."
    243287    # This is a separate class from BaseForm in order to abstract the way
    class Form(BaseForm):  
    247291    # BaseForm itself has no way of designating self.fields.
    248292    __metaclass__ = DeclarativeFieldsMetaclass
    249293
     294
    250295class BoundField(StrAndUnicode):
    251296    "A Field plus data"
     297
    252298    def __init__(self, form, field, name):
    253299        self.form = form
    254300        self.field = field
    class BoundField(StrAndUnicode):  
    294340
    295341    def as_text(self, attrs=None):
    296342        """
    297         Returns a string of HTML for representing this as an <input type="text">.
     343        Returns a string of HTML for representing this as
     344        an <input type="text">.
    298345        """
    299346        return self.as_widget(TextInput(), attrs)
    300347
    class BoundField(StrAndUnicode):  
    304351
    305352    def as_hidden(self, attrs=None):
    306353        """
    307         Returns a string of HTML for representing this as an <input type="hidden">.
     354        Returns a string of HTML for representing this as an
     355        <input type="hidden">.
    308356        """
    309357        return self.as_widget(self.field.hidden_widget(), attrs)
    310358
    class BoundField(StrAndUnicode):  
    312360        """
    313361        Returns the data for this BoundField, or None if it wasn't given.
    314362        """
    315         return self.field.widget.value_from_datadict(self.form.data, self.form.files, self.html_name)
     363        return self.field.widget.value_from_datadict(
     364                   self.form.data, self.form.files, self.html_name)
    316365    data = property(_data)
    317366
    318367    def label_tag(self, contents=None, attrs=None):
    319368        """
    320         Wraps the given contents in a <label>, if the field has an ID attribute.
    321         Does not HTML-escape the contents. If contents aren't given, uses the
    322         field's HTML-escaped label.
     369        Wraps the given contents in a <label>, if the field has an ID
     370        attribute. Does not HTML-escape the contents. If contents aren't
     371        given, uses the field's HTML-escaped label.
    323372
    324         If attrs are given, they're used as HTML attributes on the <label> tag.
     373        If attrs are given, they're used as HTML attributes on the
     374        <label> tag.
    325375        """
    326376        contents = contents or escape(self.label)
    327377        widget = self.field.widget
    328378        id_ = widget.attrs.get('id') or self.auto_id
    329379        if id_:
    330380            attrs = attrs and flatatt(attrs) or ''
    331             contents = '<label for="%s"%s>%s</label>' % (widget.id_for_label(id_), attrs, contents)
     381            contents = '<label for="%s"%s>%s</label>' % (
     382                   widget.id_for_label(id_), attrs, contents)
    332383        return mark_safe(contents)
    333384
    334385    def _is_hidden(self):
    class BoundField(StrAndUnicode):  
    339390    def _auto_id(self):
    340391        """
    341392        Calculates and returns the ID attribute for this BoundField, if the
    342         associated Form has specified auto_id. Returns an empty string otherwise.
     393        associated Form has specified auto_id. Returns an empty string
     394        otherwise.
    343395        """
    344396        auto_id = self.form.auto_id
    345397        if auto_id and '%s' in smart_unicode(auto_id):
  • django/newforms/widgets.py

    diff --git a/django/newforms/widgets.py b/django/newforms/widgets.py
    index ebbf2ab..6e7e6d0 100644
    a b __all__ = (  
    2525    'CheckboxSelectMultiple', 'MultiWidget', 'SplitDateTimeWidget',
    2626)
    2727
     28
    2829class Widget(object):
    29     is_hidden = False          # Determines whether this corresponds to an <input type="hidden">.
    30     needs_multipart_form = False # Determines does this widget need multipart-encrypted form
     30    is_hidden = False # Determines whether this corresponds to
     31                      #an <input type="hidden">.
     32    needs_multipart_form = False # Determines does this widget
     33                                 # need multipart-encrypted form
    3134
    3235    def __init__(self, attrs=None):
    3336        if attrs is not None:
    class Widget(object):  
    7780        return id_
    7881    id_for_label = classmethod(id_for_label)
    7982
     83
    8084class Input(Widget):
    8185    """
    8286    Base class for all <input> widgets (except type='checkbox' and
    class Input(Widget):  
    8589    input_type = None # Subclasses must define this.
    8690
    8791    def render(self, name, value, attrs=None):
    88         if value is None: value = ''
     92        if value is None:
     93            value = ''
    8994        final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
    9095        if value != '':
    9196            # Only add the 'value' attribute if a value is non-empty.
    9297            final_attrs['value'] = force_unicode(value)
    9398        return mark_safe(u'<input%s />' % flatatt(final_attrs))
    9499
     100
    95101class TextInput(Input):
    96102    input_type = 'text'
    97103
     104
    98105class PasswordInput(Input):
    99106    input_type = 'password'
    100107
    class PasswordInput(Input):  
    103110        self.render_value = render_value
    104111
    105112    def render(self, name, value, attrs=None):
    106         if not self.render_value: value=None
     113        if not self.render_value:
     114            value=None
    107115        return super(PasswordInput, self).render(name, value, attrs)
    108116
     117
    109118class HiddenInput(Input):
    110119    input_type = 'hidden'
    111120    is_hidden = True
    112121
     122
    113123class MultipleHiddenInput(HiddenInput):
    114124    """
    115125    A widget that handles <input type="hidden"> for fields that have a list
    116126    of values.
    117127    """
     128
    118129    def __init__(self, attrs=None, choices=()):
    119130        super(MultipleHiddenInput, self).__init__(attrs)
    120131        # choices can be any iterable
    121132        self.choices = choices
    122133
    123134    def render(self, name, value, attrs=None, choices=()):
    124         if value is None: value = []
     135        if value is None:
     136            value = []
    125137        final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
    126138        return mark_safe(u'\n'.join([(u'<input%s />' %
    127139            flatatt(dict(value=force_unicode(v), **final_attrs)))
    class MultipleHiddenInput(HiddenInput):  
    132144            return data.getlist(name)
    133145        return data.get(name, None)
    134146
     147
    135148class FileInput(Input):
    136149    input_type = 'file'
    137150    needs_multipart_form = True
    class FileInput(Input):  
    143156        "File widgets take data from FILES, not POST"
    144157        return files.get(name, None)
    145158
     159
    146160class Textarea(Widget):
     161
    147162    def __init__(self, attrs=None):
    148163        # The 'rows' and 'cols' attributes are required for HTML correctness.
    149164        self.attrs = {'cols': '40', 'rows': '10'}
    class Textarea(Widget):  
    151166            self.attrs.update(attrs)
    152167
    153168    def render(self, name, value, attrs=None):
    154         if value is None: value = ''
     169        if value is None:
     170            value = ''
    155171        value = force_unicode(value)
    156172        final_attrs = self.build_attrs(attrs, name=name)
    157173        return mark_safe(u'<textarea%s>%s</textarea>' % (flatatt(final_attrs),
    158174                conditional_escape(force_unicode(value))))
    159175
     176
    160177class DateTimeInput(Input):
    161178    input_type = 'text'
    162179    format = '%Y-%m-%d %H:%M:%S'     # '2006-10-25 14:30:59'
    class DateTimeInput(Input):  
    173190            value = value.strftime(self.format)
    174191        return super(DateTimeInput, self).render(name, value, attrs)
    175192
     193
    176194class CheckboxInput(Widget):
     195
    177196    def __init__(self, attrs=None, check_test=bool):
    178197        super(CheckboxInput, self).__init__(attrs)
    179198        # check_test is a callable that takes a value and returns True
    class CheckboxInput(Widget):  
    198217            # A missing value means False because HTML form submission does not
    199218            # send results for unselected checkboxes.
    200219            return False
    201         return super(CheckboxInput, self).value_from_datadict(data, files, name)
     220        return super(CheckboxInput, self).value_from_datadict(
     221                                           data, files, name)
     222
    202223
    203224class Select(Widget):
     225
    204226    def __init__(self, attrs=None, choices=()):
    205227        super(Select, self).__init__(attrs)
    206228        # choices can be any iterable, but we may need to render this widget
    class Select(Widget):  
    209231        self.choices = list(choices)
    210232
    211233    def render(self, name, value, attrs=None, choices=()):
    212         if value is None: value = ''
     234        if value is None:
     235            value = ''
    213236        final_attrs = self.build_attrs(attrs, name=name)
    214237        output = [u'<select%s>' % flatatt(final_attrs)]
    215238        # Normalize to string.
    216239        str_value = force_unicode(value)
    217240        for option_value, option_label in chain(self.choices, choices):
    218241            option_value = force_unicode(option_value)
    219             selected_html = (option_value == str_value) and u' selected="selected"' or ''
     242            selected_html = (option_value == str_value) and \
     243                               u' selected="selected"' or ''
    220244            output.append(u'<option value="%s"%s>%s</option>' % (
    221245                    escape(option_value), selected_html,
    222246                    conditional_escape(force_unicode(option_label))))
    223247        output.append(u'</select>')
    224248        return mark_safe(u'\n'.join(output))
    225249
     250
    226251class NullBooleanSelect(Select):
    227252    """
    228253    A Select Widget intended to be used with NullBooleanField.
    229254    """
     255
    230256    def __init__(self, attrs=None):
    231         choices = ((u'1', ugettext('Unknown')), (u'2', ugettext('Yes')), (u'3', ugettext('No')))
     257        choices = ((u'1', ugettext('Unknown')), (u'2', ugettext('Yes')),
     258                   (u'3', ugettext('No')))
    232259        super(NullBooleanSelect, self).__init__(attrs, choices)
    233260
    234261    def render(self, name, value, attrs=None, choices=()):
    class NullBooleanSelect(Select):  
    236263            value = {True: u'2', False: u'3', u'2': u'2', u'3': u'3'}[value]
    237264        except KeyError:
    238265            value = u'1'
    239         return super(NullBooleanSelect, self).render(name, value, attrs, choices)
     266        return super(NullBooleanSelect, self).render(
     267                               name, value, attrs, choices)
    240268
    241269    def value_from_datadict(self, data, files, name):
    242270        value = data.get(name, None)
    243         return {u'2': True, u'3': False, True: True, False: False}.get(value, None)
     271        return {u'2': True, u'3': False, True: True, False: False}.get(
     272                               value, None)
     273
    244274
    245275class SelectMultiple(Widget):
     276
    246277    def __init__(self, attrs=None, choices=()):
    247278        super(SelectMultiple, self).__init__(attrs)
    248279        # choices can be any iterable
    249280        self.choices = choices
    250281
    251282    def render(self, name, value, attrs=None, choices=()):
    252         if value is None: value = []
     283        if value is None:
     284            value = []
    253285        final_attrs = self.build_attrs(attrs, name=name)
    254286        output = [u'<select multiple="multiple"%s>' % flatatt(final_attrs)]
    255         str_values = set([force_unicode(v) for v in value]) # Normalize to strings.
     287        # Normalize to strings.
     288        str_values = set([force_unicode(v) for v in value])
    256289        for option_value, option_label in chain(self.choices, choices):
    257290            option_value = force_unicode(option_value)
    258             selected_html = (option_value in str_values) and ' selected="selected"' or ''
     291            selected_html = (option_value in str_values) and \
     292                               ' selected="selected"' or ''
    259293            output.append(u'<option value="%s"%s>%s</option>' % (
    260294                    escape(option_value), selected_html,
    261295                    conditional_escape(force_unicode(option_label))))
    class SelectMultiple(Widget):  
    267301            return data.getlist(name)
    268302        return data.get(name, None)
    269303
     304
    270305class RadioInput(StrAndUnicode):
    271306    """
    272307    An object used by RadioFieldRenderer that represents a single
    class RadioInput(StrAndUnicode):  
    286321        else:
    287322            label_for = ''
    288323        choice_label = conditional_escape(force_unicode(self.choice_label))
    289         return mark_safe(u'<label%s>%s %s</label>' % (label_for, self.tag(), choice_label))
     324        return mark_safe(u'<label%s>%s %s</label>' % (
     325                               label_for, self.tag(), choice_label))
    290326
    291327    def is_checked(self):
    292328        return self.value == self.choice_value
    class RadioInput(StrAndUnicode):  
    294330    def tag(self):
    295331        if 'id' in self.attrs:
    296332            self.attrs['id'] = '%s_%s' % (self.attrs['id'], self.index)
    297         final_attrs = dict(self.attrs, type='radio', name=self.name, value=self.choice_value)
     333        final_attrs = dict(self.attrs, type='radio',
     334                           name=self.name, value=self.choice_value)
    298335        if self.is_checked():
    299336            final_attrs['checked'] = 'checked'
    300337        return mark_safe(u'<input%s />' % flatatt(final_attrs))
    301338
     339
    302340class RadioFieldRenderer(StrAndUnicode):
    303341    """
    304342    An object used by RadioSelect to enable customization of radio widgets.
    class RadioFieldRenderer(StrAndUnicode):  
    310348
    311349    def __iter__(self):
    312350        for i, choice in enumerate(self.choices):
    313             yield RadioInput(self.name, self.value, self.attrs.copy(), choice, i)
     351            yield RadioInput(self.name, self.value, self.attrs.copy(),
     352                               choice, i)
    314353
    315354    def __getitem__(self, idx):
    316355        choice = self.choices[idx] # Let the IndexError propogate
    317         return RadioInput(self.name, self.value, self.attrs.copy(), choice, idx)
     356        return RadioInput(self.name, self.value, self.attrs.copy(),
     357                           choice, idx)
    318358
    319359    def __unicode__(self):
    320360        return self.render()
    class RadioFieldRenderer(StrAndUnicode):  
    324364        return mark_safe(u'<ul>\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>'
    325365                % force_unicode(w) for w in self]))
    326366
     367
    327368class RadioSelect(Select):
    328369    renderer = RadioFieldRenderer
    329370
    class RadioSelect(Select):  
    336377
    337378    def get_renderer(self, name, value, attrs=None, choices=()):
    338379        """Returns an instance of the renderer."""
    339         if value is None: value = ''
     380        if value is None:
     381            value = ''
    340382        str_value = force_unicode(value) # Normalize to string.
    341383        final_attrs = self.build_attrs(attrs)
    342384        choices = list(chain(self.choices, choices))
    class RadioSelect(Select):  
    355397        return id_
    356398    id_for_label = classmethod(id_for_label)
    357399
     400
    358401class CheckboxSelectMultiple(SelectMultiple):
     402
    359403    def render(self, name, value, attrs=None, choices=()):
    360         if value is None: value = []
     404        if value is None:
     405            value = []
    361406        has_id = attrs and 'id' in attrs
    362407        final_attrs = self.build_attrs(attrs, name=name)
    363408        output = [u'<ul>']
    364409        # Normalize to strings
    365410        str_values = set([force_unicode(v) for v in value])
    366         for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
     411        for i, (option_value, option_label) in enumerate(chain(
     412                           self.choices, choices)):
    367413            # If an ID attribute was given, add a numeric index as a suffix,
    368414            # so that the checkboxes don't all have the same ID attribute.
    369415            if has_id:
    class CheckboxSelectMultiple(SelectMultiple):  
    371417                label_for = u' for="%s"' % final_attrs['id']
    372418            else:
    373419                label_for = ''
    374                
    375             cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
     420
     421            cb = CheckboxInput(final_attrs,
     422                               check_test=lambda value: value in str_values)
    376423            option_value = force_unicode(option_value)
    377424            rendered_cb = cb.render(name, option_value)
    378425            option_label = conditional_escape(force_unicode(option_label))
    379             output.append(u'<li><label%s>%s %s</label></li>' % (label_for, rendered_cb, option_label))
     426            output.append(u'<li><label%s>%s %s</label></li>' % (
     427                           label_for, rendered_cb, option_label))
    380428        output.append(u'</ul>')
    381429        return mark_safe(u'\n'.join(output))
    382430
    class CheckboxSelectMultiple(SelectMultiple):  
    387435        return id_
    388436    id_for_label = classmethod(id_for_label)
    389437
     438
    390439class MultiWidget(Widget):
    391440    """
    392441    A widget that is composed of multiple widgets.
    class MultiWidget(Widget):  
    414463
    415464    You'll probably want to use this class with MultiValueField.
    416465    """
     466
    417467    def __init__(self, widgets, attrs=None):
    418468        self.widgets = [isinstance(w, type) and w() or w for w in widgets]
    419469        super(MultiWidget, self).__init__(attrs)
    class MultiWidget(Widget):  
    433483                widget_value = None
    434484            if id_:
    435485                final_attrs = dict(final_attrs, id='%s_%s' % (id_, i))
    436             output.append(widget.render(name + '_%s' % i, widget_value, final_attrs))
     486            output.append(widget.render(name + '_%s' % i, widget_value,
     487                                       final_attrs))
    437488        return mark_safe(self.format_output(output))
    438489
    439490    def id_for_label(self, id_):
    class MultiWidget(Widget):  
    444495    id_for_label = classmethod(id_for_label)
    445496
    446497    def value_from_datadict(self, data, files, name):
    447         return [widget.value_from_datadict(data, files, name + '_%s' % i) for i, widget in enumerate(self.widgets)]
     498        return [widget.value_from_datadict(data, files, name + '_%s' % i) \
     499               for i, widget in enumerate(self.widgets)]
    448500
    449501    def format_output(self, rendered_widgets):
    450502        """
    class MultiWidget(Widget):  
    464516        """
    465517        raise NotImplementedError('Subclasses must implement this method.')
    466518
     519
    467520class SplitDateTimeWidget(MultiWidget):
    468521    """
    469522    A Widget that splits datetime input into two <input type="text"> boxes.
    470523    """
     524
    471525    def __init__(self, attrs=None):
    472526        widgets = (TextInput(attrs=attrs), TextInput(attrs=attrs))
    473527        super(SplitDateTimeWidget, self).__init__(widgets, attrs)
    class SplitDateTimeWidget(MultiWidget):  
    476530        if value:
    477531            return [value.date(), value.time().replace(microsecond=0)]
    478532        return [None, None]
    479 
Back to Top