diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 9db76a6..2509ddb 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -474,14 +474,22 @@ class Field(object):
             else:
                 defaults['initial'] = self.get_default()
         if self.choices:
-            # Fields with choices get special treatment.
             include_blank = (self.blank or
                              not (self.has_default() or 'initial' in kwargs))
             defaults['choices'] = self.get_choices(include_blank=include_blank)
+            defaults.update(kwargs)
+            return self.choices_formfield(**defaults)
+        else:
+            defaults.update(kwargs)
+            return form_class(**defaults)
+
+    def choices_formfield(self, form_class=None, **kwargs):
+        defaults = {}
+        if form_class is None:
+            form_class = forms.TypedChoiceField
             defaults['coerce'] = self.to_python
             if self.null:
                 defaults['empty_value'] = None
-            form_class = forms.TypedChoiceField
             # Many of the subclass-specific formfield arguments (min_value,
             # max_value) don't apply for choice fields, so be sure to only pass
             # 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/tests/regressiontests/model_fields/models.py
+++ b/tests/regressiontests/model_fields/models.py
@@ -13,6 +13,7 @@ except ImportError:
     except ImportError:
         Image = None
 
+from django import forms
 from django.core.files.storage import FileSystemStorage
 from django.db import models
 from django.db.models.fields.files import ImageFieldFile, ImageField
@@ -29,6 +30,17 @@ class Bar(models.Model):
     b = models.CharField(max_length=10)
     a = models.ForeignKey(Foo, default=get_foo)
 
+class CustomIntegerFormField(forms.IntegerField):
+    def __init__(self, *args, **kwargs):
+        if 'choices' in kwargs:
+            del kwargs['choices']
+        super(CustomIntegerFormField, self).__init__(*args, **kwargs)
+
+class CustomIntegerField(models.IntegerField):
+    def choices_formfield(self, form_class=None, **kwargs):
+        return super(CustomIntegerField, self).choices_formfield(
+            form_class=CustomIntegerFormField, **kwargs)
+
 class Whiz(models.Model):
     CHOICES = (
         ('Group 1', (
@@ -44,6 +56,8 @@ class Whiz(models.Model):
         (0,'Other'),
     )
     c = models.IntegerField(choices=CHOICES, null=True)
+    d = CustomIntegerField(choices=CHOICES, default=4)
+    ts = models.DateTimeField(auto_now_add=True)
 
 class BigD(models.Model):
     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/tests/regressiontests/model_fields/tests.py
+++ b/tests/regressiontests/model_fields/tests.py
@@ -11,7 +11,8 @@ from django.db.models.fields.files import FieldFile
 from django.utils import unittest
 
 from .models import (Foo, Bar, Whiz, BigD, BigS, Image, BigInt, Post,
-    NullBooleanModel, BooleanModel, Document, RenamedField)
+    NullBooleanModel, BooleanModel, Document, RenamedField,
+    CustomIntegerFormField)
 
 # If PIL available, do these tests.
 if Image:
@@ -223,6 +224,16 @@ class ChoicesTests(test.TestCase):
         self.assertEqual(Whiz(c=None).get_c_display(), None)    # Blank value
         self.assertEqual(Whiz(c='').get_c_display(), '')        # Empty value
 
+    def test_choices_formfield_overrides(self):
+        whiz_meta = Whiz(c=1)._meta
+        field = whiz_meta.get_field_by_name('c')[0]
+        self.assertIs(type(field.formfield()),
+                forms.TypedChoiceField)
+        self.assertIs(type(whiz_meta.get_field_by_name('d')[0].formfield()),
+                CustomIntegerFormField)
+        self.assertIs(type(whiz_meta.get_field_by_name('ts')[0].formfield()),
+                forms.DateTimeField)
+
 class SlugFieldTests(test.TestCase):
     def test_slugfield_max_length(self):
         """
