【问题标题】:Why is Django (1.8.3) migrations dropping fields in migration when they're still in the model为什么 Django (1.8.3) 迁移在迁移中删除仍在模型中的字段
【发布时间】:2015-11-27 17:21:56
【问题描述】:

我在我的 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。在此迁移之前,应用工作、测试通过等。生成的迁移是:

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)

【问题讨论】:

    标签: python django django-models


    【解决方案1】:

    我的猜测是您通过创建具有相同名称的属性或方法来“隐藏”该字段。

    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.7)。删除现有字段是一个非常严重的数据丢失问题,Django 开发人员会非常重视它。

    【讨论】:

    • 是的,这正是我所做的。更新了我对 getter 方法的命名约定,不再有问题。谢谢,这让我发疯了。
    猜你喜欢
    • 1970-01-01
    • 2021-06-09
    • 2018-12-15
    • 2021-06-02
    • 1970-01-01
    • 1970-01-01
    • 2015-10-12
    • 1970-01-01
    • 2016-01-27
    相关资源
    最近更新 更多