Code

Ticket #9245: issue9245.diff

File issue9245.diff, 6.5 KB (added by ambv, 2 years ago)

Patch for 1.4RC

Line 
1Index: tests/regressiontests/model_fields/tests.py
2===================================================================
3diff --git a/django/trunk/tests/regressiontests/model_fields/tests.py b/django/trunk/tests/regressiontests/model_fields/tests.py
4--- a/django/trunk/tests/regressiontests/model_fields/tests.py  (revision 17703)
5+++ b/django/trunk/tests/regressiontests/model_fields/tests.py  (working copy)
6@@ -11,7 +11,8 @@
7 from django.utils import unittest
8 
9 from .models import (Foo, Bar, Whiz, BigD, BigS, Image, BigInt, Post,
10-    NullBooleanModel, BooleanModel, Document, RenamedField)
11+    NullBooleanModel, BooleanModel, Document, RenamedField,
12+    CustomIntegerFormField)
13 
14 # If PIL available, do these tests.
15 if Image:
16@@ -223,6 +224,16 @@
17         self.assertEqual(Whiz(c=None).get_c_display(), None)    # Blank value
18         self.assertEqual(Whiz(c='').get_c_display(), '')        # Empty value
19 
20+    def test_choices_formfield_overrides(self):
21+        whiz_meta = Whiz(c=1)._meta
22+        field = whiz_meta.get_field_by_name('c')[0]
23+        self.assertIs(type(field.formfield()),
24+                forms.TypedChoiceField)
25+        self.assertIs(type(whiz_meta.get_field_by_name('d')[0].formfield()),
26+                CustomIntegerFormField)
27+        self.assertIs(type(whiz_meta.get_field_by_name('ts')[0].formfield()),
28+                forms.DateTimeField)
29+
30 class SlugFieldTests(test.TestCase):
31     def test_slugfield_max_length(self):
32         """
33Index: tests/regressiontests/model_fields/models.py
34===================================================================
35diff --git a/django/trunk/tests/regressiontests/model_fields/models.py b/django/trunk/tests/regressiontests/model_fields/models.py
36--- a/django/trunk/tests/regressiontests/model_fields/models.py (revision 17703)
37+++ b/django/trunk/tests/regressiontests/model_fields/models.py (working copy)
38@@ -13,6 +13,7 @@
39     except ImportError:
40         Image = None
41 
42+from django import forms
43 from django.core.files.storage import FileSystemStorage
44 from django.db import models
45 from django.db.models.fields.files import ImageFieldFile, ImageField
46@@ -29,6 +30,20 @@
47     b = models.CharField(max_length=10)
48     a = models.ForeignKey(Foo, default=get_foo)
49 
50+class CustomIntegerFormField(forms.IntegerField):
51+    override_for_choices = False
52+
53+    def __init__(self, *args, **kwargs):
54+        if 'choices' in kwargs:
55+            del kwargs['choices']
56+        super(CustomIntegerFormField, self).__init__(*args, **kwargs)
57+
58+class CustomIntegerField(models.IntegerField):
59+    def formfield(self, **kwargs):
60+        if 'form_class' not in kwargs:
61+            kwargs['form_class'] = CustomIntegerFormField
62+        return super(CustomIntegerField, self).formfield(**kwargs)
63+
64 class Whiz(models.Model):
65     CHOICES = (
66         ('Group 1', (
67@@ -44,6 +59,8 @@
68         (0,'Other'),
69     )
70     c = models.IntegerField(choices=CHOICES, null=True)
71+    d = CustomIntegerField(choices=CHOICES, default=4)
72+    ts = models.DateTimeField(auto_now_add=True)
73 
74 class BigD(models.Model):
75     d = models.DecimalField(max_digits=38, decimal_places=30)
76Index: django/db/models/fields/__init__.py
77===================================================================
78diff --git a/django/trunk/django/db/models/fields/__init__.py b/django/trunk/django/db/models/fields/__init__.py
79--- a/django/trunk/django/db/models/fields/__init__.py  (revision 17704)
80+++ b/django/trunk/django/db/models/fields/__init__.py  (working copy)
81@@ -471,18 +471,19 @@
82             include_blank = (self.blank or
83                              not (self.has_default() or 'initial' in kwargs))
84             defaults['choices'] = self.get_choices(include_blank=include_blank)
85-            defaults['coerce'] = self.to_python
86-            if self.null:
87-                defaults['empty_value'] = None
88-            form_class = forms.TypedChoiceField
89-            # Many of the subclass-specific formfield arguments (min_value,
90-            # max_value) don't apply for choice fields, so be sure to only pass
91-            # the values that TypedChoiceField will understand.
92-            for k in kwargs.keys():
93-                if k not in ('coerce', 'empty_value', 'choices', 'required',
94-                             'widget', 'label', 'initial', 'help_text',
95-                             'error_messages', 'show_hidden_initial'):
96-                    del kwargs[k]
97+            if form_class.override_for_choices:
98+                defaults['coerce'] = self.to_python
99+                if self.null:
100+                    defaults['empty_value'] = None
101+                form_class = forms.TypedChoiceField
102+                # Many of the subclass-specific formfield arguments (min_value,
103+                # max_value) don't apply for choice fields, so be sure to only
104+                # pass the values that TypedChoiceField will understand.
105+                for k in kwargs.keys():
106+                    if k not in ('coerce', 'empty_value', 'choices', 'required',
107+                                'widget', 'label', 'initial', 'help_text',
108+                                'error_messages', 'show_hidden_initial'):
109+                        del kwargs[k]
110         defaults.update(kwargs)
111         return form_class(**defaults)
112 
113Index: django/forms/fields.py
114===================================================================
115diff --git a/django/trunk/django/forms/fields.py b/django/trunk/django/forms/fields.py
116--- a/django/trunk/django/forms/fields.py       (revision 17704)
117+++ b/django/trunk/django/forms/fields.py       (working copy)
118@@ -50,6 +50,7 @@
119         'required': _(u'This field is required.'),
120         'invalid': _(u'Enter a valid value.'),
121     }
122+    override_for_choices = False
123 
124     # Tracks each time a Field instance is created. Used to retain order.
125     creation_counter = 0
126@@ -182,6 +183,8 @@
127         return result
128 
129 class CharField(Field):
130+    override_for_choices = True
131+
132     def __init__(self, max_length=None, min_length=None, *args, **kwargs):
133         self.max_length, self.min_length = max_length, min_length
134         super(CharField, self).__init__(*args, **kwargs)
135@@ -209,6 +212,7 @@
136         'max_value': _(u'Ensure this value is less than or equal to %(limit_value)s.'),
137         'min_value': _(u'Ensure this value is greater than or equal to %(limit_value)s.'),
138     }
139+    override_for_choices = True
140 
141     def __init__(self, max_value=None, min_value=None, *args, **kwargs):
142         self.max_value, self.min_value = max_value, min_value
143@@ -665,6 +669,7 @@
144     cleaned to None.
145     """
146     widget = NullBooleanSelect
147+    override_for_choices = True
148 
149     def to_python(self, value):
150         """