54

当我更改help_textverbose_name为我的任何模型字段运行python manage.py makemigrations时,它会检测到这些更改并创建一个新的迁移,例如0002_xxxx.py.

我正在使用 PostgreSQL,我认为这些更改与我的数据库无关(我想知道是否存在与这些更改相关的 DBMS)。

为什么 Django 会为此类更改生成迁移?有没有选择忽略它们?

我可以手动将更改应用0002_xxxx.py到以前的迁移 ( 0001_initial.py) 并安全删除0002_xxxx.py吗?

有没有办法自动更新以前的迁移?

4

8 回答 8

19

当然,您可以使用之前的迁移来压缩它

或者,如果您根本不想输出这些迁移,您可以通过将其放入您的应用程序来覆盖makemigrationsandmigrate命令management/commands/makemigrations.py

from django.core.management.commands.makemigrations import Command
from django.db import models

IGNORED_ATTRS = ['verbose_name', 'help_text', 'choices']

original_deconstruct = models.Field.deconstruct

def new_deconstruct(self):
  name, path, args, kwargs = original_deconstruct(self)
  for attr in IGNORED_ATTRS:
    kwargs.pop(attr, None)
  return name, path, args, kwargs

models.Field.deconstruct = new_deconstruct
于 2016-09-30T23:12:23.787 回答
12

这张票解决了这个问题。

如果你只改变了help_text& django 会生成一个新的迁移;然后您可以将最新迁移的更改应用到以前的迁移并删除最新的迁移。

只需help_text将先前迁移中的更改为最新迁移中存在的 help_text 并删除最新迁移文件。*.pyc 如果存在,请确保删除相应的文件。否则会引发异常。

于 2014-10-22T17:36:27.677 回答
9

为避免不必要的迁移,您可以执行以下操作:

  1. 导致迁移的子类字段
  2. 在该字段内编写自定义解构方法
  3. 利润

例子:

from django.db import models

class CustomCharField(models.CharField):  # or any other field

    def deconstruct(self):
        name, path, args, kwargs = super(CustomCharField, self).deconstruct()
        # exclude all fields you dont want to cause migration, my example below:
        if 'help_text' in kwargs:
            del kwargs['help_text']
        if 'verbose_name' in kwargs:
            del kwargs['verbose_name']
        return name, path, args, kwargs

希望有帮助

于 2015-03-24T13:11:39.003 回答
2

正如@ChillarAnand 所指出的,有一张票可以解决这个问题,但直到现在(django 1.9.1)迁移命令还没有修复。

修复它的最少侵入性方法是创建自己的maketranslatedmigrations命令<your-project>/management/commands/maketranslatedmigrations.py

#coding: utf-8

from django.core.management.base import BaseCommand
from django.core.management.commands.makemigrations import Command as MakeMigrations


class Command(MakeMigrations):
    leave_locale_alone = True
    can_import_settings = True

    def handle(self, *app_labels, **options):
        super(Command, self).handle(*app_labels, **options)

然后你可以像原来的 makemigrations 一样使用它。

PS不要忘记__init__.py在路径上的任何地方添加文件

于 2016-01-10T08:56:39.100 回答
1

在任何模型字段中更改 verbose_name 或 verbose_name_plural 时停止生成迁移文件。

在像 src/monkey_patching/django/db/migrations/operations/change_model_options.py 这样的新文件中添加:

from django.db.migrations.operations import models

models.AlterModelOptions.ALTER_OPTION_KEYS = [
    "base_manager_name",
    "default_manager_name",
    "get_latest_by",
    "managed",
    "ordering",
    "permissions",
    "default_permissions",
    "select_on_save",
    # "verbose_name",
    # "verbose_name_plural",
]

在 django 1.11.10 中测试。

于 2020-03-02T18:29:59.790 回答
1

我为此目的编写了自定义模块

您只需将其保存在一些 utils/models.db 和所有模型中,而不是from django.db import models写入from utils import models

如果有人对此感兴趣,我可以编写一个组件并将其发布到 pypi

UPD:试试这个https://github.com/FeroxTL/django-migration-control

# models.py

# -*- coding: utf-8 -*-
from types import FunctionType
from django.db import models


class NoMigrateMixin(object):
    """
    Позволяет исключить из миграций различные поля
    """
    def deconstruct(self):
        name, path, args, kwargs = super(NoMigrateMixin, self).deconstruct()
        kwargs.pop('help_text', None)
        kwargs.pop('verbose_name', None)
        return name, path, args, kwargs


# =============================================================================
# DJANGO CLASSES
# =============================================================================

for name, cls in models.__dict__.items():
    if isinstance(cls, type):
        if issubclass(cls, models.Field):
            # Поля
            globals()[name] = type(name, (NoMigrateMixin, cls), {})
        else:
            # Всякие менеджеры
            globals()[name] = cls
    elif isinstance(cls, FunctionType):
        # Прочие функции
        globals()[name] = cls
于 2016-05-20T07:36:52.730 回答
1

从 Django 2.X 开始,使用ugettext_lazy代替ugettextgettext修复它。

于 2019-08-22T06:54:58.827 回答
0

ChillarAnand 提到的票很有帮助,但是在更新日志的最后,我没有意识到它是否已修复,或者它已在最新版本的 Django 中修复。

因此,由于我没有找到任何适用于 Django 1.9.13 的解决方案,我添加了一个小技巧settings.py

if 'makemigrations' in sys.argv:
    USE_I18N = False
    USE_L10N = False

不优雅,但它工作正常。

于 2018-06-11T18:48:07.750 回答