Django

Code

Changeset 5782

Show
Ignore:
Timestamp:
08/01/07 00:41:32 (1 year ago)
Author:
gwilson
Message:

Fixed #4228 -- Removed hardcoding of RadioFieldRenderer in the RadioSelect Widget so that the display of RadioSelects can be more easily customized. BoundField.__unicode__ also no longer special cases RadioSelect since RadioSelect.render() now returns a string like every other Widget.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/newforms/forms.py

    r5609 r5782  
    233233 
    234234    def __unicode__(self): 
    235         "Renders this field as an HTML widget." 
    236         # Use the 'widget' attribute on the field to determine which type 
    237         # of HTML widget to use. 
    238         value = self.as_widget(self.field.widget) 
    239         if not isinstance(value, basestring): 
    240             # Some Widget render() methods -- notably RadioSelect -- return a 
    241             # "special" object rather than a string. Call __unicode__() on that 
    242             # object to get its rendered value. 
    243             value = unicode(value) 
    244         return value 
     235        """Renders this field as an HTML widget.""" 
     236        return self.as_widget() 
    245237 
    246238    def _errors(self): 
     
    252244    errors = property(_errors) 
    253245 
    254     def as_widget(self, widget, attrs=None): 
     246    def as_widget(self, widget=None, attrs=None): 
     247        """ 
     248        Renders the field by rendering the passed widget, adding any HTML 
     249        attributes passed as attrs.  If no widget is specified, then the 
     250        field's default widget will be used. 
     251        """ 
     252        if not widget: 
     253            widget = self.field.widget 
    255254        attrs = attrs or {} 
    256255        auto_id = self.auto_id 
  • django/trunk/django/newforms/widgets.py

    r5609 r5782  
    217217 
    218218class RadioInput(StrAndUnicode): 
    219     "An object used by RadioFieldRenderer that represents a single <input type='radio'>." 
     219    """ 
     220    An object used by RadioFieldRenderer that represents a single 
     221    <input type='radio'>. 
     222    """ 
     223 
    220224    def __init__(self, name, value, attrs, choice, index): 
    221225        self.name, self.value = name, value 
     
    240244 
    241245class RadioFieldRenderer(StrAndUnicode): 
    242     "An object used by RadioSelect to enable customization of radio widgets." 
     246    """ 
     247    An object used by RadioSelect to enable customization of radio widgets. 
     248    """ 
     249 
    243250    def __init__(self, name, value, attrs, choices): 
    244251        self.name, self.value, self.attrs = name, value, attrs 
     
    254261 
    255262    def __unicode__(self): 
    256         "Outputs a <ul> for this set of radio fields." 
     263        return self.render() 
     264 
     265    def render(self): 
     266        """Outputs a <ul> for this set of radio fields.""" 
    257267        return u'<ul>\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>' % force_unicode(w) for w in self]) 
    258268 
    259269class RadioSelect(Select): 
    260     def render(self, name, value, attrs=None, choices=()): 
    261         "Returns a RadioFieldRenderer instance rather than a Unicode string." 
     270 
     271    def __init__(self, *args, **kwargs): 
     272        self.renderer = kwargs.pop('renderer', None) 
     273        if not self.renderer: 
     274            self.renderer = RadioFieldRenderer 
     275        super(RadioSelect, self).__init__(*args, **kwargs) 
     276 
     277    def get_renderer(self, name, value, attrs=None, choices=()): 
     278        """Returns an instance of the renderer.""" 
    262279        if value is None: value = '' 
    263280        str_value = force_unicode(value) # Normalize to string. 
    264281        final_attrs = self.build_attrs(attrs) 
    265         return RadioFieldRenderer(name, str_value, final_attrs, list(chain(self.choices, choices))) 
     282        choices = list(chain(self.choices, choices)) 
     283        return self.renderer(name, str_value, final_attrs, choices) 
     284 
     285    def render(self, name, value, attrs=None, choices=()): 
     286        return self.get_renderer(name, value, attrs, choices).render() 
    266287 
    267288    def id_for_label(self, id_): 
  • django/trunk/tests/regressiontests/forms/tests.py

    r5686 r5782  
    55form_tests = r""" 
    66>>> from django.newforms import * 
     7>>> from django.newforms.widgets import RadioFieldRenderer 
    78>>> import datetime 
    89>>> import time 
     
    615616</ul> 
    616617 
    617 The render() method returns a RadioFieldRenderer object, whose str() is a <ul>
     618RadioSelect uses a RadioFieldRenderer to render the individual radio inputs
    618619You can manipulate that object directly to customize the way the RadioSelect 
    619620is rendered. 
    620621>>> w = RadioSelect() 
    621 >>> r = w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) 
     622>>> r = w.get_renderer('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) 
    622623>>> for inp in r: 
    623624...     print inp 
     
    645646beatle J R Ringo False 
    646647 
     648You can create your own custom renderers for RadioSelect to use. 
     649>>> class MyRenderer(RadioFieldRenderer): 
     650...    def render(self): 
     651...        return u'<br />\n'.join([unicode(choice) for choice in self]) 
     652>>> w = RadioSelect(renderer=MyRenderer) 
     653>>> print w.render('beatle', 'G', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) 
     654<label><input type="radio" name="beatle" value="J" /> John</label><br /> 
     655<label><input type="radio" name="beatle" value="P" /> Paul</label><br /> 
     656<label><input checked="checked" type="radio" name="beatle" value="G" /> George</label><br /> 
     657<label><input type="radio" name="beatle" value="R" /> Ringo</label> 
     658 
    647659A RadioFieldRenderer object also allows index access to individual RadioInput 
    648660objects. 
    649661>>> w = RadioSelect() 
    650 >>> r = w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) 
     662>>> r = w.get_renderer('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) 
    651663>>> print r[1] 
    652664<label><input type="radio" name="beatle" value="P" /> Paul</label>