I have a django core app called "foocore".
There are several optional pluging-like apps. For example "superfoo".
In my case every plugin adds a new choice in a model CharField which belongs to "foocore".
Django migrations detect changes if the list of choices get changed.
I think this is not necessary. At least one other developer thinks the same:
https://code.djangoproject.com/ticket/22837
class ActivePlugin(models.Model):
plugin_name = models.CharField(max_length=32, choices=get_active_plugins())
The code to get the choices:
class get_active_plugins(object):
def __iter__(self):
for item in ....:
yield item
The core "foocore" gets used in several projects and every installation has a different set of plugins. Django tries to create useless migrations ....
Is there a way to work around this?
I had a similar problem. My choices were dynamic (all years from a starting point to the present) and every year the first time
makemigrations
was run it generated new migrations for the new choice. The solution I found was customizing the field so thechoices
change wouldn't be detected bymakemigrations
:I had a similar problem with a custom field that I made for a Django 1.6 project that had the same general structure. I came to the following solution which works alright:
That is for python 3, for python 2 you have to specify the metaclass as follows:
See this bug report and discussion for more info: https://code.djangoproject.com/ticket/22837
The proposed solution was to use a callable as the argument for choices, but it appears this has not been executed for fields but for forms only.
If you really need dynamic choices than a
ForeignKey
is the best solution.An alternative solution can be to add the requirement through a custom clean method for the field and/or creating a custom form. Form fields do support callable
choices
.See this answer for more info: https://stackoverflow.com/a/33514551/54017