TNT*_*TNT 2 python django overriding makemigrations
我有一个 python2.7 django 项目(我知道,我在 20 世纪!),其中有一些模型。我需要重写 makemigrations ,以便迁移文件名的形式为 0001.py、0002.py 等,而不是像 0001_initial.py、0002_model1.py 等那样,默认情况下会发生这种情况。
我已经研究了如何创建自定义管理.py 命令,并且能够覆盖 makemigrations 命令。目前我的自定义命令(python2.7)的代码如下所示:
路径/to/project/app/management/commands/makemigrations.py
from django.core.management.commands.makemigrations import Command as CoreMakeMigrationsCommand
class Command(CoreMakeMigrationsCommand):
def handle(self, *args, **options):
super(Command, self).handle(*args, **options)
Run Code Online (Sandbox Code Playgroud)
目前它只是调用原来的 makemigrations 而已。autodetector.py我需要能够修改决定文件命名的方式(这是 makemigrations 流程的一部分)。在这个文件中,有suggest_name如下所示的方法:
@classmethod
def suggest_name(cls, ops):
"""
Given a set of operations, suggest a name for the migration they might
represent. Names are not guaranteed to be unique, but put some effort
into the fallback name to avoid VCS conflicts if possible.
"""
if len(ops) == 1:
if isinstance(ops[0], operations.CreateModel):
return ops[0].name_lower
elif isinstance(ops[0], operations.DeleteModel):
return "delete_%s" % ops[0].name_lower
elif isinstance(ops[0], operations.AddField):
return "%s_%s" % (ops[0].model_name_lower, ops[0].name_lower)
elif isinstance(ops[0], operations.RemoveField):
return "remove_%s_%s" % (ops[0].model_name_lower, ops[0].name_lower)
elif ops:
if all(isinstance(o, operations.CreateModel) for o in ops):
return "_".join(sorted(o.name_lower for o in ops))
return "auto_%s" % get_migration_name_timestamp()
Run Code Online (Sandbox Code Playgroud)
上面的代码从这里调用,在同一个文件中的另一个方法中arrange_for_graph:
for i, migration in enumerate(migrations):
if i == 0 and app_leaf:
migration.dependencies.append(app_leaf)
if i == 0 and not app_leaf:
new_name = "0001_%s" % migration_name if migration_name else "0001_initial"
else:
new_name = "%04i_%s" % (
next_number,
migration_name or self.suggest_name(migration.operations)[:100],
)
Run Code Online (Sandbox Code Playgroud)
我是覆盖核心文件的新手,无法弄清楚如何仅覆盖原始自定义命令文件中的这一部分,以便满足我的要求?
另外,请告知这将如何影响后续对 makemigrations 的调用,因为它们将依赖于新的迁移文件集(具有修改后的名称)。
谢谢
好的,我是这样做的。
创建一个 makemigrations.py 文件(如 django 文档中所示,用于覆盖 manage.py 命令),在其中创建一个继承“django.core.management.commands.makemigrations.Command”的 Command 类并覆盖方法write_migration_files,如下所示:
from django.core.management.commands.makemigrations import Command as CoreMakeMigrationsCommand
class Command(CoreMakeMigrationsCommand):
def write_migration_files(self, changes):
for item in changes.values():
print('Overriding default names of migrations supplied by django core')
item[0].name = item[0].name.split('_')[0]
super(Command, self).write_migration_files(changes)
Run Code Online (Sandbox Code Playgroud)