django 如何进行迁移操作(例如AddField)检测是否正在应用或恢复迁移?

7uzetpgm  于 2023-06-25  发布在  Go
关注(0)|答案(1)|浏览(113)

一个很好的例子是django.db.migrations.AddField
假设我创建了一个简单的迁移,例如:

from django.db import migrations, models

class Migration(migrations.Migration):
    dependencies = []

    operations = [
        migrations.AddField(
            model_name="foo",
            name="bar",
            field=models.TextField(blank=True, null=True),
        ),
    ]

运行迁移将导致bar字段被添加,恢复到以前的迁移将导致bar字段被删除。
但是,当我深入了解AddField类时,我没有看到用于检测应用迁移方向的逻辑。

class AddField(FieldOperation):
    field: Field[Any, Any] = ...
    preserve_default: bool = ...
    def __init__(
        self,
        model_name: str,
        name: str,
        field: Field[Any, Any],
        preserve_default: bool = ...,
    ) -> None: ...

我需要为收集的数据创建一个类似的函数,该函数可以根据对数据所基于的模型所做的更改应用/恢复更改。此函数将以类似于AddField的方式在迁移中使用,并需要检测用户是否正在应用或恢复迁移。

ne5o7dgx

ne5o7dgx1#

migrate管理命令将检测这是否是一个新的(即向前)或先前(即,向后)迁移,并根据迁移的方向调用database_forwardsdatabase_backwards方法。Operation子类不需要知道init的方向:

class AddField(FieldOperation):
    ...
    def database_forwards(self, app_label, schema_editor, from_state, to_state):
        to_model = to_state.apps.get_model(app_label, self.model_name)
        if self.allow_migrate_model(schema_editor.connection.alias, to_model):
            from_model = from_state.apps.get_model(app_label, self.model_name)
            field = to_model._meta.get_field(self.name)
            if not self.preserve_default:
                field.default = self.field.default
            schema_editor.add_field(
                from_model,
                field,
            )
            if not self.preserve_default:
                field.default = NOT_PROVIDED

    def database_backwards(self, app_label, schema_editor, from_state, to_state):
        from_model = from_state.apps.get_model(app_label, self.model_name)
        if self.allow_migrate_model(schema_editor.connection.alias, from_model):
            schema_editor.remove_field(
                from_model, from_model._meta.get_field(self.name)
            )

这在文档中有部分解释,特别是在反转迁移和编写您自己的迁移操作部分。

相关问题