我正在使用一个元类来自动将我的Django模型数据库表名称从驼峰式设置为'_'分隔的名称,例如MyGreatModel
的表名将类似于appname_my_great_model
,而不是默认的appname_mygreatmodel
:
class PrettyModelBase(ModelBase):
def __new__(cls, name, bases, attrs):
super_new = ModelBase.__new__(cls, name, bases, attrs)
module_name = camel_to_underscore(name)
model_module = sys.modules[cls.__module__]
app_label = super_new.__module__.split('.')[-2]
db_table = '%s_%s' % (app_label, module_name)
if not getattr(super_new._meta, 'proxy', False):
super_new._meta.db_table = db_table
return super_new
class BaseModel(models.Model):
__metaclass__ = PrettyModelBase
class Meta:
abstract = True
class MyGreatModel(BaseModel):
somefield = models.TextField(default="")
但是,迁移似乎并没有使用这个db_table
名称。如果我运行makemigrations,则CreateModel
在此模型的db_table
中不会显示options
。如果我将其硬编码在class Meta
的{{1}}中,则可以。此外,如果我检查要与MyGreatModel
一起运行的SQL,那么它表明它将创建python manage.py sqlmigrate...
表,而不是带分隔符的表名。
但是,如果我运行此迁移,然后在Django shell中检查模型,那么appname_mygreatmodel
会显示MyGreatModel._meta.db_table
,正如我期望从我的元类中看到的那样。如果我为CreateModel手动添加my_great_model
属性0001的init迁移选项,那么以后的迁移也都可以,但是Django应该自动执行此操作...
为什么Django迁移没有在这里使用db_table
?
我正在使用db_table
。
感谢您的帮助
答案 0 :(得分:1)
这个问题在django-developers邮件列表中重新提出:https://groups.google.com/forum/#!msg/django-developers/ncMCwMF2J3g/V3guuDbJCwAJ
Django迁移使用model._meta.original_attrs
来确定元类的定义:https://github.com/django/django/blob/stable/2.2.x/django/db/migrations/state.py#L454
因此,如果您要动态更改创建后的model._meta
,则还需要相应地更改其original_attrs
字典。我认为这应该有效(未试用)。