diff options
| author | Brian Rosner <brosner@gmail.com> | 2008-06-26 16:53:53 +0000 |
|---|---|---|
| committer | Brian Rosner <brosner@gmail.com> | 2008-06-26 16:53:53 +0000 |
| commit | c349ba4cfc2d137da393bddbda6e78fdb98c9c81 (patch) | |
| tree | b42749fa7132f1c5f5f8c4efd6dbb4aaa8758afe /django | |
| parent | c8da0874c78ed4c6e1ad08cc78228799a333f76c (diff) | |
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.
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@7771 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django')
| -rw-r--r-- | django/contrib/admin/options.py | 2 | ||||
| -rw-r--r-- | django/contrib/admin/widgets.py | 46 |
2 files changed, 36 insertions, 12 deletions
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index acc7d3962a..27f8676a64 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -198,7 +198,7 @@ class BaseModelAdmin(object): formfield = db_field.formfield(**kwargs) # Don't wrap raw_id fields. Their add function is in the popup window. if not db_field.name in self.raw_id_fields: - formfield.widget.render = widgets.RelatedFieldWidgetWrapper(formfield.widget.render, db_field.rel, self.admin_site) + formfield.widget = widgets.RelatedFieldWidgetWrapper(formfield.widget, db_field.rel, self.admin_site) return formfield if db_field.choices and db_field.name in self.radio_fields: diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index e7ea4aa129..4ae8889ac4 100644 --- a/django/contrib/admin/widgets.py +++ b/django/contrib/admin/widgets.py @@ -2,6 +2,8 @@ Form Widget classes specific to the Django admin site. """ +import copy + from django import newforms as forms from django.newforms.widgets import RadioFieldRenderer from django.newforms.util import flatatt @@ -162,21 +164,34 @@ class ManyToManyRawIdWidget(ForeignKeyRawIdWidget): return True return False -class RelatedFieldWidgetWrapper(object): +class RelatedFieldWidgetWrapper(forms.Widget): """ - This class is a wrapper whose __call__() method mimics the interface of a - Widget's render() method. + This class is a wrapper to a given widget to add the add icon for the + admin interface. """ - def __init__(self, render_func, rel, admin_site): - self.render_func, self.rel = render_func, rel + def __init__(self, widget, rel, admin_site): + self.is_hidden = widget.is_hidden + self.needs_multipart_form = widget.needs_multipart_form + self.attrs = widget.attrs + self.choices = widget.choices + self.widget = widget + self.rel = rel # so we can check if the related object is registered with this AdminSite self.admin_site = admin_site - def __call__(self, name, value, *args, **kwargs): + def __deepcopy__(self, memo): + obj = copy.copy(self) + obj.widget = copy.deepcopy(self.widget, memo) + obj.attrs = self.widget.attrs + memo[id(self)] = obj + return obj + + def render(self, name, value, *args, **kwargs): from django.conf import settings rel_to = self.rel.to related_url = '../../../%s/%s/' % (rel_to._meta.app_label, rel_to._meta.object_name.lower()) - output = [self.render_func(name, value, *args, **kwargs)] + self.widget.choices = self.choices + output = [self.widget.render(name, value, *args, **kwargs)] if rel_to in self.admin_site._registry: # If the related object has an admin interface: # TODO: "id_" is hard-coded here. This should instead use the correct # API to determine the ID dynamically. @@ -185,7 +200,16 @@ class RelatedFieldWidgetWrapper(object): output.append(u'<img src="%simg/admin/icon_addlink.gif" width="10" height="10" alt="Add Another"/></a>' % settings.ADMIN_MEDIA_PREFIX) return mark_safe(u''.join(output)) - def __deepcopy__(self, memo): - # There's no reason to deepcopy admin_site, etc, so just return self. - memo[id(self)] = self - return self + def build_attrs(self, extra_attrs=None, **kwargs): + "Helper function for building an attribute dictionary." + self.attrs = self.widget.build_attrs(extra_attrs=None, **kwargs) + return self.attrs + + def value_from_datadict(self, data, files, name): + return self.widget.value_from_datadict(data, files, name) + + def _has_changed(self, initial, data): + return self.widget._has_changed(initial, data) + + def id_for_label(self, id_): + return self.widget.id_for_label(id_) |
