gue*_*tli 16 python django database-migration
我有一个名为"foocore"的django核心应用程序.
有几个可选的类似插件的应用程序.例如"superfoo".
在我的例子中,每个插件都在CharField模型中添加了一个新选项,该模型属于"foocore".
如果选择列表发生更改,Django迁移会检测更改.
我认为这不是必要的.至少有一位其他开发者认为相同:
https://code.djangoproject.com/ticket/22837
class ActivePlugin(models.Model):
plugin_name = models.CharField(max_length=32, choices=get_active_plugins())
Run Code Online (Sandbox Code Playgroud)
获取选择的代码:
class get_active_plugins(object):
def __iter__(self):
for item in ....:
yield item
Run Code Online (Sandbox Code Playgroud)
核心"foocore"在几个项目中使用,每个安装都有一组不同的插件.Django试图创建无用的迁移....
有办法解决这个问题吗?
Wol*_*lph 11
有关详细信息,请参阅此错误报告和讨论:https://code.djangoproject.com/ticket/22837
建议的解决方案是使用callable作为选择的参数,但看起来这并没有针对字段执行,而是仅针对表单执行.
如果你真的需要动态选择而不是ForeignKey
最佳解决方案.
另一种解决方案可以是通过字段的自定义清理方法和/或创建自定义表单来添加需求.表单字段确实支持可调用choices
.
有关详细信息,请参阅此答案:https://stackoverflow.com/a/33514551/54017
我有一个类似的问题。我的选择是动态的(从起点到现在的所有年份),每年第一次makemigrations
运行它都会为新选择生成新的迁移。我找到的解决方案是自定义字段,这样choices
更改就不会被检测到makemigrations
:
from django.db import models
class YearField(models.IntegerField):
description = "A year from 2015 to the present"
def deconstruct(self):
name, path, args, kwargs = super(YearField, self).deconstruct()
# Ignore choice changes when generating migrations
kwargs.pop('choices', None)
return (name, path, args, kwargs)
Run Code Online (Sandbox Code Playgroud)
我有一个类似的问题,我为一个具有相同通用结构的Django 1.6项目制作的自定义字段.我找到了以下可行的解决方案:
class ActivePluginMeta(ModelBase):
def __new__(cls, name, bases, attrs):
# Override choices attr
cls = models.base.ModelBase.__new__(cls, name, bases, attrs)
setattr(cls._meta.get_field('plugin_name'), 'choices', cls.plugin_name_choices)
return cls
class ActivePlugin(models.Model, metaclass=ActivePluginMeta):
plugin_name_choices = get_active_plugins()
plugin_name = models.CharField(max_length=32, choices=[])
Run Code Online (Sandbox Code Playgroud)
对于python 3,对于python 2,你必须指定元类,如下所示:
class ActivePlugin(models.Model):
__metaclass__ = ActivePluginMeta
plugin_name_choices = get_active_plugins()
plugin_name = models.CharField(max_length=32, choices=[])
Run Code Online (Sandbox Code Playgroud)