From 4e96dac450e3546bf86220932f5a64fea1ad5bac Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Tue, 10 Sep 2013 13:56:49 -0400 Subject: [PATCH] Fixed #19298 -- Added MultiValueField.__deepcopy__ Thanks nick.phillips at otago.ac.nz for the report. --- django/forms/fields.py | 5 +++++ tests/forms_tests/tests/test_forms.py | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/django/forms/fields.py b/django/forms/fields.py index 7a59a3d664..80550c232b 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -977,6 +977,11 @@ class MultiValueField(Field): f.required = False self.fields = fields + def __deepcopy__(self, memo): + result = super(MultiValueField, self).__deepcopy__(memo) + result.fields = tuple([x.__deepcopy__(memo) for x in self.fields]) + return result + def validate(self, value): pass diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py index 3204ec9437..640f48fe44 100644 --- a/tests/forms_tests/tests/test_forms.py +++ b/tests/forms_tests/tests/test_forms.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals +import copy import datetime from django.core.files.uploadedfile import SimpleUploadedFile @@ -1793,6 +1794,26 @@ class FormsTestCase(TestCase): self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data, {'name' : 'fname lname'}) + def test_multivalue_deep_copy(self): + """ + #19298 -- MultiValueField needs to override the default as it needs + to deep-copy subfields: + """ + class ChoicesField(MultiValueField): + def __init__(self, fields=(), *args, **kwargs): + fields = (ChoiceField(label='Rank', + choices=((1,1),(2,2))), + CharField(label='Name', max_length=10)) + super(ChoicesField, self).__init__(fields=fields, *args, **kwargs) + + + field = ChoicesField() + field2 = copy.deepcopy(field) + self.assertTrue(isinstance(field2, ChoicesField)) + self.assertFalse(id(field2.fields) == id(field.fields)) + self.assertFalse(id(field2.fields[0].choices) == + id(field.fields[0].choices)) + def test_multivalue_optional_subfields(self): class PhoneField(MultiValueField): def __init__(self, *args, **kwargs):