简体   繁体   中英

Django creates pointless migrations on choices list change

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.

class Quote(models.Model):
    severity = models.IntegerField(choices=get_severity_choices)
    ...

class get_severity_choices(object):
    def __iter__(self):
        for item in SEVERITY_CHOICES:
            yield item

where

SEVERITY_CHOICES = (
    (1, 'Low'),
    (2, 'Medium'),
    (3, 'High'),
)

However, I'm getting an error message:

quoting.Quote.severity: (fields.E004) 'choices' must be an iterable (e.g., a list or tuple).

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 (eg, a list or tuple) consisting itself of iterables of exactly two items (eg [(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 (eg, 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 hacking choices 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM