Django 1.11模型迁移操作不适用

时间:2018-11-19 13:43:14

标签: python django python-3.x django-migrations

我在迁移过程中的操作已执行,而有关付款人字段的任何信息都没有进入数据库。

这是我的模特:

class User(AbstractBaseUser, PermissionsMixin, WithCsvImportMixin):
    first_name = models.CharField(_('first name'), max_length=30, blank=False)
    last_name = models.CharField(_('last name'), max_length=30, blank=False)
    email = models.EmailField(_('email address'),
                              unique=True, blank=False)
    external_id = models.CharField(_('external id'), db_index=True, max_length=50, unique=True, blank=False, null=True)
    is_staff = models.BooleanField(_('staff status'), default=False)
    is_active = models.BooleanField(_('active'), default=True)
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
    payer = models.CharField(_('payer'), max_length=50, blank=False, default='')

有关付款人字段的第一次迁移:

# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-11-15 21:58
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('authenticate', '0012_auto_20181112_1631'),
    ]

    operations = [
        migrations.AddField(
            model_name='user',
            name='payer',
            field=models.CharField(default='', max_length=50, verbose_name='payer'),
        ),
    ]

这是执行的,但是结果似乎没有应用于数据库:

# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-11-15 22:01
from django.db import migrations, transaction

from xxx.authenticate.models import User # The xxx is here to replace the actual application name

def create_payer_names(apps, schema_editor):
    with transaction.atomic():
        for user in User.objects.all():
            if user.external_id != "":
                user.payer = user.external_id
                user.save()

class Migration(migrations.Migration):

    dependencies = [
        ('authenticate', '0013_user_payer'),
    ]

    operations = [
        migrations.RunPython(create_payer_names, migrations.RunPython.noop, atomic=True),
    ]

我的数据库已经填充,并且每个用户都有一个external_id

>>> from xxx.authenticate.models import User
>>> for item in User.objects.all():
...     print(item.external_id)
... 
043819FZAFR
762944FZAFR
285895FZAFR
671800FZAFR
924618FZAFR
068805FZAFR
232544FZAFR
130978FZAFR
412568FZAFR
600003FZAFR
254624FZAFR
417745FZAFR
068280FZAFR
031971FZAFR
141936FZAFR
>>> 

这是以前的迁移的空结果:

>>> for item in User.objects.all():
...     print(item.payer)
... 























>>> 

以下是命令的输出:manage.py showmigrations

authenticate
 [X] 0001_initial
 [X] 0002_auto_20171103_1722
 [X] 0003_auto_20171109_1206
 [X] 0004_auto_20180329_1049
 [X] 0005_auto_20180507_1123
 [X] 0006_user_by_pass_generates_invoice
 [X] 0007_auto_20180524_1732
 [X] 0008_auto_20180530_1525
 [X] 0009_auto_20180801_1644
 [X] 0010_user_payment
 [X] 0011_remove_user_payment
 [X] 0012_auto_20181112_1631
 [X] 0013_user_payer
 [X] 0014_auto_20181115_2301

当我这样做时:

./manage.py migrate authenticate 0014

输出如下:

Running migrations:
  No migrations to apply.

有人可以向我解释我做错了什么,为什么不执行应有的迁移操作?

1 个答案:

答案 0 :(得分:2)

在迁移中,您应该使用apps.get_model来获得User模型。有关更多信息,请参见[数据迁移]上的文档。

def create_payer_names(apps, schema_editor):
    User = apps.get_model('authentication', 'User')
    with transaction.atomic():
        ...

showmigrations的输出显示迁移0014已被应用。这就是为什么您收到No migrations to apply消息的原因。

 [X] 0014_auto_20181115_2301

您可以先伪造0013迁移,重新运行0014迁移。

./manage.py migrate --fake authenticate 0013
./manage.py migrate authenticate 0014