diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 7e56bddffe940..c08e9777c185d 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -631,6 +631,8 @@ def deconstruct(self): equals_comparison = {"choices", "validators"} for name, default in possibles.items(): value = getattr(self, attr_overrides.get(name, name)) + if isinstance(value, CallableChoiceIterator): + value = value.choices_func # Do correct kind of comparison if name in equals_comparison: if value != default: diff --git a/tests/field_deconstruction/tests.py b/tests/field_deconstruction/tests.py index 47f1655d63f5f..3b10ee00917c2 100644 --- a/tests/field_deconstruction/tests.py +++ b/tests/field_deconstruction/tests.py @@ -113,6 +113,16 @@ def test_choices_iterable(self): self.assertEqual(args, []) self.assertEqual(kwargs, {"choices": normalize_choices("012345")}) + def test_choices_callable(self): + def get_choices(): + return [(i, str(i)) for i in range(3)] + + field = models.IntegerField(choices=get_choices) + name, path, args, kwargs = field.deconstruct() + self.assertEqual(path, "django.db.models.IntegerField") + self.assertEqual(args, []) + self.assertEqual(kwargs, {"choices": get_choices}) + def test_csi_field(self): field = models.CommaSeparatedIntegerField(max_length=100) name, path, args, kwargs = field.deconstruct()