I\'m trying to create a model with a choices field using a callable, so that Django doesn\'t create migrations when a choices list changes, as stated in this question here.
I think you're mixing up the choices
argument on a Model
field, and that on a forms.ChoiceField
field. In a model, choices
must be an interable - you cannot pass a callable:
choices
: An iterable (e.g., a list or tuple) consisting itself of iterables of exactly two items (e.g. [(A, B), (A, B) ...]) to use as choices for this field.
Your get_severity_choices
class isn't being recognised as an iterable because Django expects it to subclass collections.Iterable rather than just expose an __iter__
method.
You can pass a callable to a FormField
:
choices
: Either an iterable (e.g., a list or tuple) of 2-tuples to use as choices for this field, or a callable that returns such an iterable.
For a Model
field however you must specify your choices beforehand. Also from the docs:
Note that
choices
can be any iterable object – not necessarily a list or tuple. This lets you construct choices dynamically. But if you find yourself hackingchoices
to be dynamic, you’re probably better off using a proper database table with a ForeignKey.choices
is meant for static data that doesn’t change much, if ever.
As regards why Django creates the seemingly useless migrations, there is some discussion about that in this ticket:
This is by design. There are several reasons, not least of which ... that datamigrations at points in history need to have a full accurate representation of the models, including all their options, not just those which affect the database.