Django

Code

Show
Ignore:
Timestamp:
06/26/08 11:53:53 (7 months ago)
Author:
brosner
Message:

newforms-admin: Fixed #7541 -- RelatedFieldWidgetWrapper? now wraps the widget and not the just the render function which caused some stale values. Thanks lukas and Doug Napoleone.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/newforms-admin/django/contrib/admin/options.py

    r7638 r7771  
    199199            # Don't wrap raw_id fields. Their add function is in the popup window. 
    200200            if not db_field.name in self.raw_id_fields: 
    201                 formfield.widget.render = widgets.RelatedFieldWidgetWrapper(formfield.widget.render, db_field.rel, self.admin_site) 
     201                formfield.widget = widgets.RelatedFieldWidgetWrapper(formfield.widget, db_field.rel, self.admin_site) 
    202202            return formfield 
    203203         
  • django/branches/newforms-admin/django/contrib/admin/widgets.py

    r7626 r7771  
    22Form Widget classes specific to the Django admin site. 
    33""" 
     4 
     5import copy 
    46 
    57from django import newforms as forms 
     
    163165        return False 
    164166 
    165 class RelatedFieldWidgetWrapper(object): 
    166     """ 
    167     This class is a wrapper whose __call__() method mimics the interface of a 
    168     Widget's render() method. 
    169     """ 
    170     def __init__(self, render_func, rel, admin_site): 
    171         self.render_func, self.rel = render_func, rel 
     167class RelatedFieldWidgetWrapper(forms.Widget): 
     168    """ 
     169    This class is a wrapper to a given widget to add the add icon for the 
     170    admin interface. 
     171    """ 
     172    def __init__(self, widget, rel, admin_site): 
     173        self.is_hidden = widget.is_hidden 
     174        self.needs_multipart_form = widget.needs_multipart_form 
     175        self.attrs = widget.attrs 
     176        self.choices = widget.choices 
     177        self.widget = widget 
     178        self.rel = rel 
    172179        # so we can check if the related object is registered with this AdminSite 
    173180        self.admin_site = admin_site 
    174181 
    175     def __call__(self, name, value, *args, **kwargs): 
     182    def __deepcopy__(self, memo): 
     183        obj = copy.copy(self) 
     184        obj.widget = copy.deepcopy(self.widget, memo) 
     185        obj.attrs = self.widget.attrs 
     186        memo[id(self)] = obj 
     187        return obj 
     188 
     189    def render(self, name, value, *args, **kwargs): 
    176190        from django.conf import settings 
    177191        rel_to = self.rel.to 
    178192        related_url = '../../../%s/%s/' % (rel_to._meta.app_label, rel_to._meta.object_name.lower()) 
    179         output = [self.render_func(name, value, *args, **kwargs)] 
     193        self.widget.choices = self.choices 
     194        output = [self.widget.render(name, value, *args, **kwargs)] 
    180195        if rel_to in self.admin_site._registry: # If the related object has an admin interface: 
    181196            # TODO: "id_" is hard-coded here. This should instead use the correct 
     
    186201        return mark_safe(u''.join(output)) 
    187202 
    188     def __deepcopy__(self, memo): 
    189         # There's no reason to deepcopy admin_site, etc, so just return self. 
    190         memo[id(self)] = self 
    191         return self 
     203    def build_attrs(self, extra_attrs=None, **kwargs): 
     204        "Helper function for building an attribute dictionary." 
     205        self.attrs = self.widget.build_attrs(extra_attrs=None, **kwargs) 
     206        return self.attrs 
     207 
     208    def value_from_datadict(self, data, files, name): 
     209        return self.widget.value_from_datadict(data, files, name) 
     210 
     211    def _has_changed(self, initial, data): 
     212        return self.widget._has_changed(initial, data) 
     213 
     214    def id_for_label(self, id_): 
     215        return self.widget.id_for_label(id_)