web-dev-qa-db-ja.com

Django help_textとverbose_nameの変更のために移行を行うのはなぜですか?

モデルフィールドのいずれかでhelp_textまたはverbose_nameを変更してpython manage.py makemigrationsを実行すると、これらの変更が検出され、0002_xxxx.pyなどの新しい移行が作成されます。

私はPostgreSQLを使用していますが、これらの変更はデータベースとは無関係だと思います(これらの変更が関係するDBMSはまったく存在しないのでしょうか)。

Djangoがそのような変更の移行を生成するのはなぜですか?それらを無視するオプションはありますか?

0002_xxxx.pyから以前の移行(0001_initial.py)への変更を手動で適用し、0002_xxxx.pyを安全に削除できますか?

以前の移行を自動的に更新する方法はありますか?

41
utapyngo

あなたは 前の移行でそれを押しつぶす 、確かにできます。

または、これらの移行をまったく出力したくない場合は、アプリのmanagement/commands/makemigrations.pyにこれを配置することで、makemigrationsおよびmigrateコマンドをオーバーライドできます。

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
15
Nick Retallack

このチケット 問題に対処しました。

help_text&Djangoのみを変更した場合は、新しい移行が生成されます。最新の移行から以前の移行への変更を適用し、最新の移行を削除できます。

以前の移行のhelp_textを最新の移行に存在するhelp_textに変更し、最新の移行ファイルを削除するだけです。対応する*.pycファイルが存在する場合は、必ず削除してください。それ以外の場合は、例外が発生します。

10
ChillarAnand

不要な移行を回避するには次のように実行できます。

  1. 移行を引き起こすサブクラスフィールド
  2. そのフィールド内にカスタムdeconstructメソッドを記述します
  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

お役に立てば幸いです

8
user3025188

@ChillarAnandが指摘したように、この問題を解決するチケットがありますが、これまで(Django 1.9.1)、移行コマンドは修正されていませんでした。

それを修正する最も邪魔にならない方法は、<your-project>/management/commands/maketranslatedmigrations.pyに独自のmaketranslatedmigrationsコマンドを作成することです。

#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ファイルを追加することを忘れないでください

2
katomaso

私はその目的のためにカスタムモジュールを書きました

必要なのは、from Django.db import models write from utils import modelsの代わりに、いくつかのutils /models.dbとすべてのモデルに保存することです。

誰かがそれに興味を持っているなら、私はコンポーネントを書いてそれを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
1
FeroxTL

ChillarAnandが言及しているチケットは非常に役立ちますが、変更ログの最終段階で、修正されたかどうか、または最新バージョンのDjangoで修正されたかどうかがわかりませんでした。

したがって、Django 1.9.13の解決策が見つからなかったため、settings.pyに少しハックを追加しました。

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

エレガントではありませんが、問題なく動作します。

0
nashuald

Django 1.11.10でテスト済み。

Model.verbose_nameまたはModelを変更したら、移行ファイルの生成を停止します。 verbose_name_plural。

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",
]

0

Django 2.Xから、ugettextまたはgettextの代わりにugettext_lazyを使用すると修正されます。

0
kogexo