web-dev-qa-db-ja.com

すでに入力されているモデルを使用して、null以外の一意のフィールドを追加します

いくつかのエントリがあるサーバーで実行されているアプリに1つのモデルがあります。このモデルに一意でnullではないSlugFieldを追加する必要があります。 SlugFieldは、trading_nameに基づいて入力されます。この新しいフィールドを追加し、保存方法を変更するために、モデルを変更しました。

class Supplier(StatusModel):
    SLUG_MAX_LENGTH = 210
    slug = models.SlugField(unique=True, max_length=SLUG_MAX_LENGTH)
    trading_name = models.CharField(max_length=200, verbose_name=_('trading name'))
    ...

    def save(self, *args, **kwargs):
        self.slug = orig = slugify(self.trading_name)[:Supplier.SLUG_MAX_LENGTH]

        for x in itertools.count(1):
            if not Supplier.objects.filter(slug=self.slug).exists():
                break
            # Truncate the original slug dynamically. Minus 1 for the hyphen.
            self.slug = "%s-%d" % (orig[:Supplier.SLUG_MAX_LENGTH - len(str(x)) - 1], x)

        self.full_clean()
        super(Supplier, self).save(*args, **kwargs)

モデルを変更した後、manage.py makemigrationsを実行し、次の移行を出力として取得しました。

class Migration(migrations.Migration):

    dependencies = [
        ('opti', '0003_auto_20141226_1755'),
    ]

    operations = [
        migrations.AddField(
            model_name='supplier',
            name='slug',
            field=models.SlugField(unique=True, default='', max_length=210),
            preserve_default=False,
        ),
    ]

一意の定数のためにデフォルト値が機能しないため、manage.py migrateを実行できません。

私の質問は次のとおりです。Django 1.7でこれを行うにはどうすればよいですか?スキーマの変更を適用し、データベースに現在のエントリを保持する必要があります。

20
MatheusJardimB

残念ながら、答えは見つかりませんでしたが、1つの解決策を作成できました。

  • 最初に、スラッグフィールドをnull許容にする移行を作成しました。
  • 次に、モデルのすべての行に適切な値をスラッグ列に入力する別の移行を作成しました。
  • 次に、列に非NULL制約を追加する別の移行。
26
MatheusJardimB

モデルの変更(フィールドの追加、変更など)を行ってから、manage.py makemigrationsを呼び出し、manage.py migrateを使用して移行を適用します。

null=Trueを使用してフィールドを追加すると、たとえば次のようになります。スクリプトを作成して1回入力します

それ以外の場合、移行内のフィールドに入力する必要がある場合は、カスタムフィールドを作成できます。 https://docs.djangoproject.com/en/1.7/ref/migration-operations/#writing-your-own

2
bakkal