2

我正在使用元类自动将我的 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_tableoptions此模型中。如果我在其中硬编码它class MetaMyGreatModel那么它就可以了。此外,如果我检查要运行的 SQL,python manage.py sqlmigrate...那么它表明它将创建appname_mygreatmodel表,而不是分隔表名。

但是,如果我确实运行此迁移,然后在 Django shell 中检查模型,那么会按照我对元类的期望MyGreatModel._meta.db_table显示。my_great_model如果我为 CreateModel 手动添加db_table属性 0001 init 迁移选项,那么后续迁移也一切正常,但我认为 Django 应该自动执行此操作......

为什么 Django 迁移在db_table这里没有出现?

我正在使用Django==1.10.5.

谢谢你的帮助

4

1 回答 1

2

这个问题在 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相应地改变它的 dict。我认为这应该有效(未经测试)。

于 2019-06-27T12:55:09.720 回答