diff --git a/django/forms/fields.py b/django/forms/fields.py
index 621d380..a9dca5c 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -757,7 +757,14 @@ class ChoiceField(Field):
 
     def __deepcopy__(self, memo):
         result = super(ChoiceField, self).__deepcopy__(memo)
-        result._choices = copy.deepcopy(self._choices, memo)
+
+        if hasattr(self, '_choices_as_callable'):
+            result_choices = self._choices_as_callable()
+        else:
+            result_choices = copy.deepcopy(self._choices, memo)
+
+        result._set_choices(result_choices)
+
         return result
 
     def _get_choices(self):
@@ -767,7 +774,12 @@ class ChoiceField(Field):
         # Setting choices also sets the choices on the widget.
         # choices can be any iterable, but we call list() on it because
         # it will be consumed more than once.
-        self._choices = self.widget.choices = list(value)
+        if callable(value):
+            self._choices = value()
+            self._choices_as_callable = value
+        else:
+            self._choices = self.widget.choices = list(value)
+
 
     choices = property(_get_choices, _set_choices)
 
diff --git a/tests/regressiontests/forms/tests/fields.py b/tests/regressiontests/forms/tests/fields.py
index 3fe2cd2..945a2ae 100644
--- a/tests/regressiontests/forms/tests/fields.py
+++ b/tests/regressiontests/forms/tests/fields.py
@@ -49,7 +49,6 @@ def fix_os_paths(x):
     else:
         return x
 
-
 class FieldsTests(SimpleTestCase):
 
     def assertWidgetRendersTo(self, field, to):
@@ -893,6 +892,27 @@ class FieldsTests(SimpleTestCase):
         f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=False, empty_value=None)
         self.assertEqual(None, f.clean(''))
 
+    def test_choicefield_callable(self):
+        choices = lambda: [('J', 'John'), ('P', 'Paul')]
+        f = ChoiceField(choices=choices)
+        self.assertEqual(u'J', f.clean('J'))
+      
+    def test_choicefield_callable_may_evaluate_to_different_values(self):
+        choices = []
+        def choices_as_callable():
+            return choices
+
+        class ChoiceFieldForm(Form):
+            choicefield = ChoiceField(choices=choices_as_callable)
+
+        choices = [('J', 'John'), ('P', 'Paul')]
+        form = ChoiceFieldForm()
+        self.assertTrue("John" in form.as_p())
+
+        choices = [('M', 'Marie'),]
+        form = ChoiceFieldForm()
+        self.assertTrue("Marie" in form.as_p())
+
     # NullBooleanField ############################################################
 
     def test_nullbooleanfield_1(self):
