diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index c48ffa6..f4c2751 100644
|
a
|
b
|
|
| | 1 | import copy |
| 1 | 2 | from functools import update_wrapper, partial |
| 2 | 3 | import warnings |
| 3 | 4 | |
| … |
… |
class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)):
|
| 130 | 131 | # passed to formfield_for_dbfield override the defaults. |
| 131 | 132 | for klass in db_field.__class__.mro(): |
| 132 | 133 | if klass in self.formfield_overrides: |
| 133 | | kwargs = dict(self.formfield_overrides[klass], **kwargs) |
| | 134 | kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs) |
| 134 | 135 | return db_field.formfield(**kwargs) |
| 135 | 136 | |
| 136 | 137 | # For any other type of field, just call its formfield() method. |
diff --git a/tests/regressiontests/admin_widgets/models.py b/tests/regressiontests/admin_widgets/models.py
index 2e45279..2977b86 100644
|
a
|
b
|
class Member(models.Model):
|
| 20 | 20 | @python_2_unicode_compatible |
| 21 | 21 | class Band(models.Model): |
| 22 | 22 | name = models.CharField(max_length=100) |
| | 23 | style = models.CharField(max_length=20) |
| 23 | 24 | members = models.ManyToManyField(Member) |
| 24 | 25 | |
| 25 | 26 | def __str__(self): |
diff --git a/tests/regressiontests/admin_widgets/tests.py b/tests/regressiontests/admin_widgets/tests.py
index 0b016d8..76aa9f4 100644
|
a
|
b
|
from django.contrib.admin import widgets
|
| 10 | 10 | from django.contrib.admin.tests import AdminSeleniumWebDriverTestCase |
| 11 | 11 | from django.core.files.storage import default_storage |
| 12 | 12 | from django.core.files.uploadedfile import SimpleUploadedFile |
| 13 | | from django.db.models import DateField |
| | 13 | from django.db.models import CharField, DateField |
| 14 | 14 | from django.test import TestCase as DjangoTestCase |
| 15 | 15 | from django.test.utils import override_settings |
| 16 | 16 | from django.utils import translation |
| … |
… |
class AdminFormfieldForDBFieldTests(TestCase):
|
| 112 | 112 | self.assertFormfield(models.Event, 'start_date', forms.TextInput, |
| 113 | 113 | formfield_overrides={DateField: {'widget': forms.TextInput}}) |
| 114 | 114 | |
| | 115 | def testFormfieldOverridesWidgetInstances(self): |
| | 116 | """ |
| | 117 | Test that widget instances in formfield_overrides are not shared between |
| | 118 | different fields. (#19423) |
| | 119 | """ |
| | 120 | class BandAdmin(admin.ModelAdmin): |
| | 121 | formfield_overrides = { |
| | 122 | CharField: {'widget': forms.TextInput(attrs={'size':'10'})} |
| | 123 | } |
| | 124 | ma = BandAdmin(models.Band, admin.site) |
| | 125 | f1 = ma.formfield_for_dbfield(models.Band._meta.get_field('name'), request=None) |
| | 126 | f2 = ma.formfield_for_dbfield(models.Band._meta.get_field('style'), request=None) |
| | 127 | self.assertNotEqual(f1.widget, f2.widget) |
| | 128 | self.assertEqual(f1.widget.attrs['maxlength'], '100') |
| | 129 | self.assertEqual(f2.widget.attrs['maxlength'], '20') |
| | 130 | self.assertEqual(f2.widget.attrs['size'], '10') |
| | 131 | |
| 115 | 132 | def testFieldWithChoices(self): |
| 116 | 133 | self.assertFormfield(models.Member, 'gender', forms.Select) |
| 117 | 134 | |