mirror of
https://github.com/django/django.git
synced 2025-11-19 11:15:44 +00:00
Fix field deepcopy to copy error_messages dict
Ensure Field.__deepcopy__ creates an independent copy of error_messages. Prevents changes to error messages in one form field instance from affecting others. Addresses shared mutable error_messages issue (#issue).
This commit is contained in:
parent
06909fe084
commit
2f38240802
2 changed files with 53 additions and 0 deletions
|
|
@ -199,6 +199,7 @@ class Field:
|
|||
result = copy.copy(self)
|
||||
memo[id(self)] = result
|
||||
result.widget = copy.deepcopy(self.widget, memo)
|
||||
result.error_messages = self.error_messages.copy()
|
||||
result.validators = self.validators[:]
|
||||
return result
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import copy
|
||||
|
||||
from django.forms import ChoiceField, Field, Form, Select
|
||||
from django.test import SimpleTestCase
|
||||
|
||||
|
|
@ -35,6 +37,56 @@ class BasicFieldsTests(SimpleTestCase):
|
|||
self.assertEqual(f.fields['field1'].widget.choices, [('1', '1')])
|
||||
self.assertEqual(f.fields['field2'].widget.choices, [('2', '2')])
|
||||
|
||||
def test_field_deepcopies_error_messages(self):
|
||||
"""
|
||||
Test that __deepcopy__ creates a deep copy of the error_messages dict.
|
||||
Modifying error_messages on one field instance should not affect other
|
||||
instances.
|
||||
"""
|
||||
class MyForm(Form):
|
||||
field1 = Field()
|
||||
field2 = Field()
|
||||
|
||||
form1 = MyForm()
|
||||
form2 = MyForm()
|
||||
|
||||
# Store original error message
|
||||
original_error = str(form2.fields['field1'].error_messages['required'])
|
||||
|
||||
# Modify error_messages on form1's field1
|
||||
form1.fields['field1'].error_messages['required'] = 'Custom error for form1'
|
||||
|
||||
# form2's field1 should not be affected
|
||||
self.assertEqual(
|
||||
form2.fields['field1'].error_messages['required'],
|
||||
original_error
|
||||
)
|
||||
|
||||
# form1's field2 should not be affected either
|
||||
self.assertEqual(
|
||||
form1.fields['field2'].error_messages['required'],
|
||||
original_error
|
||||
)
|
||||
|
||||
# Adding a new error message to form1's field1 should not affect form2
|
||||
form1.fields['field1'].error_messages['custom'] = 'New custom error'
|
||||
self.assertNotIn('custom', form2.fields['field1'].error_messages)
|
||||
|
||||
def test_field_direct_deepcopy_error_messages(self):
|
||||
"""
|
||||
Test that directly deepcopying a field creates independent error_messages.
|
||||
"""
|
||||
field1 = Field(error_messages={'required': 'Original required error'})
|
||||
field2 = copy.deepcopy(field1)
|
||||
|
||||
# Modify field1's error_messages
|
||||
field1.error_messages['required'] = 'Modified required error'
|
||||
field1.error_messages['new_error'] = 'A new error'
|
||||
|
||||
# field2 should not be affected
|
||||
self.assertEqual(field2.error_messages['required'], 'Original required error')
|
||||
self.assertNotIn('new_error', field2.error_messages)
|
||||
|
||||
|
||||
class DisabledFieldTests(SimpleTestCase):
|
||||
def test_disabled_field_has_changed_always_false(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue