首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django迁移错误:您不能更改M2M字段,也不能添加或删除M2M字段上的through=

Django迁移错误:您不能更改M2M字段,也不能添加或删除M2M字段上的through=
EN

Stack Overflow用户
提问于 2014-11-14 18:20:26
回答 11查看 26.1K关注 0票数 78

我正在尝试将M2M字段修改为ForeignKey字段。当我运行syncdb时,命令validate没有显示任何问题:

代码语言:javascript
复制
ValueError: Cannot alter field xxx into yyy they are not compatible types (you cannot alter to or from M2M fields, or add or remove through= on M2M fields)

所以我不能进行迁移。

代码语言:javascript
复制
class InstituteStaff(Person):
    user                 = models.OneToOneField(User, blank=True, null=True)
    investigation_area   = models.ManyToManyField(InvestigationArea, blank=True,)
    investigation_group  = models.ManyToManyField(InvestigationGroup, blank=True)
    council_group        = models.ForeignKey(CouncilGroup, null=True, blank=True)
    #profiles            = models.ManyToManyField(Profiles, null = True, blank = True)
    profiles             = models.ForeignKey(Profiles, null = True, blank = True)

这是我的第一个Django项目,所以欢迎任何建议。

EN

回答 11

Stack Overflow用户

发布于 2016-08-30 17:34:28

我偶然发现了这一点,虽然我不太关心我的数据,但我仍然不想删除整个数据库。因此,我打开迁移文件并将AlterField()命令更改为RemoveField()AddField()命令,这样就可以很好地工作。我丢失了特定字段的数据,但没有其他数据。

也就是说。

代码语言:javascript
复制
migrations.AlterField(
    model_name='player',
    name='teams',
    field=models.ManyToManyField(related_name='players', through='players.TeamPlayer', to='players.Team'),
),

代码语言:javascript
复制
migrations.RemoveField(
    model_name='player',
    name='teams',
),
migrations.AddField(
    model_name='player',
    name='teams',
    field=models.ManyToManyField(related_name='players', through='players.TeamPlayer', to='players.Team'),
),
票数 104
EN

Stack Overflow用户

发布于 2018-07-16 03:12:33

无数据丢失示例

我会说:如果机器不能为我们做些什么,那就让我们帮助它吧!

因为OP在这里提出的问题可能有多个突变,所以我将尝试以一种简单的方式来解释如何解决这类问题。

让我们假设我们有一个模型(在应用程序中称为users),如下所示:

代码语言:javascript
复制
from django.db import models


class Person(models.Model):
    name = models.CharField(max_length=128)

    def __str__(self):
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person)

    def __str__(self):
        return self.name

但在一段时间后,我们需要添加成员加入的日期。所以我们想要这个:

代码语言:javascript
复制
class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership') # <-- through model

    def __str__(self):
        return self.name

# and through Model itself
class Membership(models.Model):
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    date_joined = models.DateField()

现在,通常你会遇到和OP写的一样的问题。要解决此问题,请执行以下步骤:

  • 从这一点开始:

从django.db导入模型类Person(models.Model):name = models.CharField(max_length=128) def __str__(self):返回self.name类组(models.Model):name = models.CharField(max_length=128) members = models.ManyToManyField(Person) def __str__(self):通过模型返回模型并运行python manage.py makemigrations (,但不放置through Group.members 字段中的属性仍为):

从django.db导入模型类Person(models.Model):name = models.CharField(max_length=128) def __str__(self):return self.name类组(models.Model):name = models.CharField(max_length=128) members = models.ManyToManyField(Person) # <--还没有通过属性!models.DateField()

  • create __str__(self):return self.name class Membership(models.Model):#<-通过模型person = models.ForeignKey(Person,on_delete=models.CASCADE) self.name= models.ForeignKey( group,on_delete=models.CASCADE) date_joined = def使用python manage.py makemigrations users --empty命令创建空迁移并在python中创建转换脚本(更多关于python迁移here的信息),这将为旧字段(Group.members)创建新关系(Membership)。它可能看起来像这样:由Django A.B在YYYY-MM-DD HH:MM import datetime from django.db import migrations def create_through_relations(apps,schema_editor):group = apps.get_model('users',' Group ') Membership = apps.get_model('users','Membership') for group in Group.objects.all():for member in group.members.all():Membership( person=member,group=group,date_joined=datetime.date.today( ) .save()类迁移(migrations.Migration):dependencies = ('myapp','0005_create_models'),operations =myapp reverse_code=migrations.RunPython.noop),

  • 删除Group模型中的members字段并运行python manage.py makemigrations,因此,我们的Group将如下所示:

类组(models.Model):name = models.CharField(max_length=128)

  • add members字段Group模型,但现在使用through属性并运行python manage.py makemigrations

类组(成员):名称=成员( through='Membership') )models.Model=models.CharField(Person,max_length=128

就是这样!

现在,您需要在代码中以一种新的方式更改成员的创建-通过模型。更多关于here的信息。

您也可以选择整理它,通过squashing这些迁移。

票数 62
EN

Stack Overflow用户

发布于 2014-12-02 17:53:53

可能的解决方法:

  • 使用ForeignKey关系创建一个名为profiles1的新字段,并且不要修改profiles。进行并运行迁移。您可能需要related_name参数来防止冲突。执行后续迁移,删除原始字段。然后执行另一个迁移,将profiles1重命名回profiles。显然,新的迁移字段中不会有数据。https://docs.djangoproject.com/en/1.7/ref/migration-operations/

  • 编写一个自定义迁移

您可能希望使用makemigrationmigration,而不是syncdb

您的InstituteStaff是否有要保留的数据?

票数 24
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26927705

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档