#12048: MultiWidget does not define __deepcopy__
-------------------------------------------------+--------------------------
Reporter: powderflask <[email protected]> | Owner: nobody
Status: new | Milestone: 1.2
Component: Forms | Version: SVN
Keywords: | Stage: Unreviewed
Has_patch: 1 |
-------------------------------------------------+--------------------------
django.forms.!MultiWidget defines an instance variable, {{{ widgets }}},
which is a list of widgets. However, it does not override the
__deepcopy__() method in the Widget base class to make a copy of this
instance variable. A deepcopy of the widgets is needed when an instance
when a django Form containing a Field that uses a !MultiWidget is
instantiated, otherwise all such forms have a reference to the same
widgets list rather than their own copy.
The patch is simple - override __deepcopy__() in !MultiWidget to make a
copy of widgets. A proposed patch is attached.
Replicating the problem requires that we extend !MultiWidget, make a
deepcopy of the widget, then alter one of the widgets in some way. Here
is a minimal example that demonstrates the issue - applying the patch
fixes the issue.
{{{
from django import forms
from django.utils.encoding import StrAndUnicode, force_unicode
from django.utils.safestring import mark_safe
#####################################################
## Simplified ChoiceWithOtherWidget
## original downloaded from: http://www.djangosnippets.org/snippets/863/
#####################################################
class ChoiceWithOtherWidget(forms.MultiWidget):
"""MultiWidget for use with ChoiceWithOtherField."""
def __init__(self, choices=[]):
widgets = [
forms.RadioSelect(choices=choices),
forms.TextInput
]
super(ChoiceWithOtherWidget, self).__init__(widgets)
def _set_choices(self, choices):
""" When choices are set for this widget, we want to pass those
along to the Select widget"""
self.widgets[0].choices = choices
def _get_choices(self):
""" The choices for this widget are the Select widget's choices"""
return self.widgets[0].choices
choices = property(_get_choices, _set_choices)
def decompress(self, value):
if not value:
return [None, None]
return value
#################################################
## Minimal code to reproduces bug
#################################################
from copy import deepcopy
widget1 = ChoiceWithOtherWidget(choices=['A','B','C'])
widget2 = deepcopy(widget1)
widget2.choices=['X','Y','Z']
widget1.choices
widget2.choices
}}}
Here is the output from running the sample code above in a shell before
the patch was applied:
{{{
>>> widget1 = ChoiceWithOtherWidget(choices=['A','B','C'])
>>> widget2 = deepcopy(widget1)
>>> widget2.choices=['X','Y','Z']
>>>
>>> widget1.choices
['X', 'Y', 'Z']
>>> widget2.choices
['X', 'Y', 'Z']
}}}
... and after the patch was applied:
{{{
>>> widget1 = ChoiceWithOtherWidget(choices=['A','B','C'])
>>> widget2 = deepcopy(widget1)
>>> widget2.choices=['X','Y','Z']
>>>
>>> widget1.choices
['A', 'B', 'C']
>>> widget2.choices
['X', 'Y', 'Z']
}}}
--
Ticket URL: <http://code.djangoproject.com/ticket/12048>
Django <http://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---