为什么Django(1.8.3)迁移会在迁移时丢弃字段,因为它们仍在模型中

时间:2015-11-27 17:21:56

标签: python django django-models

我在我的django应用程序中为模型添加了一个文本字段,然后突然应用了我的迁移,我测试了左右两侧的测试。事实证明,迁移决定放弃我模型中仍然存在的字段。

在继续之前,一些相关的代码。首先,受影响的模型:

class CandidateProfile(models.Model):

    user_profile = models.ForeignKey(UserProfile, related_name="candidate_profile", null=True, blank=True)
    facebook_url = models.CharField(max_length=200, default="")
    website = models.CharField(max_length=200, default="")
    primary_email = models.CharField(max_length=100, default="")
    party = models.ForeignKey(PoliticalParty, related_name="candidate_party", null=True, blank=True)
    uploaded_picture = models.CharField(max_length=200, default="")
    ref_id = models.CharField(db_index=True, max_length=50, default="")

    create_date = models.DateTimeField(auto_now_add=True)
    update_date = models.DateTimeField(auto_now=True)

我添加的字段为facebook_url。在此迁移之前,app工作,测试传递等。生成的迁移是:

class Migration(migrations.Migration):

    dependencies = [
        ('users', '0001_initial'),
    ]

    operations = [
        migrations.RemoveField(
            model_name='candidateprofile',
            name='party',
        ),
        migrations.AddField(
            model_name='candidateprofile',
            name='facebook_url',
            field=models.CharField(default=b'', max_length=200),
        ),
    ]

修复本身很简单,我可以回滚迁移,并手动删除migrations.RemoveField。单元测试做了他们应该做的事情,让我知道我搞砸了一些东西,但我仍然担心这样的事情要进入生产,丢失数据并且不得不从备份中恢复。

我的问题是:为什么Django认为该字段应该删除,即使它显然是模型中的外键?

编辑:删除字段后,我尝试更改party属性的属性,以查看Django使用的任何差异机制是否会将其选中。没有骰子,更改related_namenullblank没有做任何事情。正在运行makemigrations未检测到任何更改。

另外,外键型号供参考:

class PoliticalParty(models.Model):

    name = models.CharField(max_length="100")
    full_name = models.CharField(max_length="255")
    abbreviation = models.CharField(max_length="20")
    ref_id = models.CharField(max_length="50", default="", db_index=True)

    create_date = models.DateTimeField(auto_now_add=True)
    update_date = models.DateTimeField(auto_now=True)

1 个答案:

答案 0 :(得分:1)

我的猜测是你被影子了#39;该字段,通过创建具有相同名称的属性或方法。

class CandidateProfile(models.Model):
    party = models.ForeignKey(PoliticalParty, related_name="candidate_party", null=True, blank=True)

    def party(self):
        """This method will replace the model field"""
        return ''

如果您没有这样做,请尝试提供可以重新创建问题的说明(最好使用最新的1.8.8版本)。删除现有字段是一个非常严重的数据丢失问题,Django开发人员会认真对待它。