Django 会创建无用的迁移吗?

Dav*_* D. 3 django django-models

当我更改verbose_nameDjango 模型的属性时,Django 将生成相关的迁移(运行make migrations command).

但是,如果不应用迁移(migrate命令),更改似乎会应用到整个 Django 项目。我认为这是因为verbose_name它是在 Django 级别而不是数据库级别使用的。

这让我想知道:这个迁移文件的目的是什么?

Wil*_*sem 5

Django 对所使用的后端进行了抽象。事实上,您可以通过更改文件来使用不同的后端settings.py。事实上你可以自己定义一个后端。

因此,对模型的所有更改都会对数据库产生影响。例如,您可以定义一个使用verbose_name列的后端作为“注释字符串”,您可以经常添加到数据库端的此类列。例如,如果您定义choices,那么对于某些数据库,后端可以尝试在数据库级别强制执行这些选择。

正如前面所说,Django 的目标是在不知道所使用的后端的情况下工作,因此它的目标是保守,并针对大量模型更改进行迁移。对于其中一些,后端将决定简单地不执行任何操作。因此,不会构建任何查询,数据库端也不会进行任何更改。您确实可以将此类更改视为“无用的迁移”。但请记住,如果您稍后使用不同的后端,这些“无用的迁移”实际上可能会有所作为。

由于此类迁移不会在数据库端执行任何操作,因此通常不会耗费时间。您可能希望将迁移文件[Django-doc] 压缩”在一起,从而减少使用的迁移文件的数量。迁移仍然是文件的一部分,但由于不涉及查询,因此通常不会造成太大损害。

此外,您实际上可以修补deconstruct字段上的函数,以便help_text等不再出现在调用结果中deconstruct,因此对“检测器”不可见。这个要点脚本展示了一种修补makemigration命令的方法:

"""
Patch the creation of database migrations in Django
Import this early from `__init__.py``.
- Don't want verbose_name changes in the migrations file.
- Don't want help_text in the migrations file.
"""
from functools import wraps

from django.db.models import Field


def patch_deconstruct(old_func, condition):
    """
    Patch the ``Field.deconstruct`` to remove useless information.
    This only happens on internal apps, not third party apps.
    """

    @wraps(old_func)
    def new_deconstruct(self):
        name, path, args, kwargs = old_func(self)
        # AutoField has no model on creation, but can be skipped
        if hasattr(self, 'model') and condition(self):
            kwargs.pop('verbose_name', None)
            kwargs.pop('help_text', None)
        return name, path, args, kwargs
    return new_deconstruct


Field.deconstruct = patch_deconstruct(Field.deconstruct, lambda self: self.model.__module__.startswith('apps.'))
Run Code Online (Sandbox Code Playgroud)

  • @radoh:你可以“猴子修补”“destruct”:https://gist.github.com/vdboor/e3754e19551f2fbbcc31b01eec99ee8e 我认为可以制作一个包来通过设置来完成此操作,就像你所描述的那样。所以从技术上来说是可以的。 (2认同)