diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 9db76a6..2509ddb 100644
a
|
b
|
class Field(object):
|
474 | 474 | else: |
475 | 475 | defaults['initial'] = self.get_default() |
476 | 476 | if self.choices: |
477 | | # Fields with choices get special treatment. |
478 | 477 | include_blank = (self.blank or |
479 | 478 | not (self.has_default() or 'initial' in kwargs)) |
480 | 479 | defaults['choices'] = self.get_choices(include_blank=include_blank) |
| 480 | defaults.update(kwargs) |
| 481 | return self.choices_formfield(**defaults) |
| 482 | else: |
| 483 | defaults.update(kwargs) |
| 484 | return form_class(**defaults) |
| 485 | |
| 486 | def choices_formfield(self, form_class=None, **kwargs): |
| 487 | defaults = {} |
| 488 | if form_class is None: |
| 489 | form_class = forms.TypedChoiceField |
481 | 490 | defaults['coerce'] = self.to_python |
482 | 491 | if self.null: |
483 | 492 | defaults['empty_value'] = None |
484 | | form_class = forms.TypedChoiceField |
485 | 493 | # Many of the subclass-specific formfield arguments (min_value, |
486 | 494 | # max_value) don't apply for choice fields, so be sure to only pass |
487 | 495 | # the values that TypedChoiceField will understand. |
diff --git a/tests/regressiontests/model_fields/models.py b/tests/regressiontests/model_fields/models.py
index 4dcfb17..f3e18ca 100644
a
|
b
|
except ImportError:
|
13 | 13 | except ImportError: |
14 | 14 | Image = None |
15 | 15 | |
| 16 | from django import forms |
16 | 17 | from django.core.files.storage import FileSystemStorage |
17 | 18 | from django.db import models |
18 | 19 | from django.db.models.fields.files import ImageFieldFile, ImageField |
… |
… |
class Bar(models.Model):
|
29 | 30 | b = models.CharField(max_length=10) |
30 | 31 | a = models.ForeignKey(Foo, default=get_foo) |
31 | 32 | |
| 33 | class CustomIntegerFormField(forms.IntegerField): |
| 34 | def __init__(self, *args, **kwargs): |
| 35 | if 'choices' in kwargs: |
| 36 | del kwargs['choices'] |
| 37 | super(CustomIntegerFormField, self).__init__(*args, **kwargs) |
| 38 | |
| 39 | class CustomIntegerField(models.IntegerField): |
| 40 | def choices_formfield(self, form_class=None, **kwargs): |
| 41 | return super(CustomIntegerField, self).choices_formfield( |
| 42 | form_class=CustomIntegerFormField, **kwargs) |
| 43 | |
32 | 44 | class Whiz(models.Model): |
33 | 45 | CHOICES = ( |
34 | 46 | ('Group 1', ( |
… |
… |
class Whiz(models.Model):
|
44 | 56 | (0,'Other'), |
45 | 57 | ) |
46 | 58 | c = models.IntegerField(choices=CHOICES, null=True) |
| 59 | d = CustomIntegerField(choices=CHOICES, default=4) |
| 60 | ts = models.DateTimeField(auto_now_add=True) |
47 | 61 | |
48 | 62 | class BigD(models.Model): |
49 | 63 | d = models.DecimalField(max_digits=38, decimal_places=30) |
diff --git a/tests/regressiontests/model_fields/tests.py b/tests/regressiontests/model_fields/tests.py
index 5d3d42e..1493963 100644
a
|
b
|
from django.db.models.fields.files import FieldFile
|
11 | 11 | from django.utils import unittest |
12 | 12 | |
13 | 13 | from .models import (Foo, Bar, Whiz, BigD, BigS, Image, BigInt, Post, |
14 | | NullBooleanModel, BooleanModel, Document, RenamedField) |
| 14 | NullBooleanModel, BooleanModel, Document, RenamedField, |
| 15 | CustomIntegerFormField) |
15 | 16 | |
16 | 17 | # If PIL available, do these tests. |
17 | 18 | if Image: |
… |
… |
class ChoicesTests(test.TestCase):
|
223 | 224 | self.assertEqual(Whiz(c=None).get_c_display(), None) # Blank value |
224 | 225 | self.assertEqual(Whiz(c='').get_c_display(), '') # Empty value |
225 | 226 | |
| 227 | def test_choices_formfield_overrides(self): |
| 228 | whiz_meta = Whiz(c=1)._meta |
| 229 | field = whiz_meta.get_field_by_name('c')[0] |
| 230 | self.assertIs(type(field.formfield()), |
| 231 | forms.TypedChoiceField) |
| 232 | self.assertIs(type(whiz_meta.get_field_by_name('d')[0].formfield()), |
| 233 | CustomIntegerFormField) |
| 234 | self.assertIs(type(whiz_meta.get_field_by_name('ts')[0].formfield()), |
| 235 | forms.DateTimeField) |
| 236 | |
226 | 237 | class SlugFieldTests(test.TestCase): |
227 | 238 | def test_slugfield_max_length(self): |
228 | 239 | """ |