为什么Django会为help_text和verbose_name更改进行迁移?

时间:2014-10-22 09:01:59

标签: python django database-migration django-1.7 django-1.9

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

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

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

我是否可以手动安全地将0002_xxxx.py更改应用到上一次迁移(0001_initial.py)并安全删除0002_xxxx.py

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

8 个答案:

答案 0 :(得分:14)

你可以squash it with the previous migration,确定。

或者,如果您根本不想输出这些迁移,可以在makemigrations中将migratemanagement/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

答案 1 :(得分:9)

This ticket解决了这个问题。

如果您只更改了help_text&amp; django产生了新的迁移;然后,您可以将最新迁移的更改应用于以前的迁移,并删除最新的迁移。

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

答案 2 :(得分:7)

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

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

    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
    

    希望有所帮助

答案 3 :(得分: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完全相同。

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

答案 4 :(得分:1)

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

您只需将其保存在某些utils / models.db和所有模型中,而不是from django.db import modelsfrom 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

答案 5 :(得分: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中测试。

答案 6 :(得分:0)

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

所以,由于我没有为Django 1.9.13找到任何解决方案,我在settings.py添加了一些小问题:

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

不优雅,但效果还可以。

答案 7 :(得分:0)

在Django 2.X中,使用ugettext_lazy而不是ugettextgettext对其进行了修复。