loa*_*oar 47 migration django foreign-keys manytomanyfield
我正在尝试将M2M字段修改为ForeignKey字段.命令validate显示没有问题,当我运行syncdb时:
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)
Run Code Online (Sandbox Code Playgroud)
所以我无法进行迁移.
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)
Run Code Online (Sandbox Code Playgroud)
这是我的第一个Django项目,所以欢迎任何建议.
wan*_*tel 59
我偶然发现了这一点,虽然我并不关心我的数据,但我仍然不想删除整个数据库.所以我打开了迁移文件并将AlterField()命令更改为a RemoveField()和一个AddField()运行良好的命令.我丢失了关于特定字段的数据,但没有别的.
即
migrations.AlterField(
model_name='player',
name='teams',
field=models.ManyToManyField(related_name='players', through='players.TeamPlayer', to='players.Team'),
),
Run Code Online (Sandbox Code Playgroud)
至
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'),
),
Run Code Online (Sandbox Code Playgroud)
tur*_*kus 22
我想说:如果机器不能为我们做点什么,那就让我们帮忙吧!
因为OP放在这里的问题可以有多个突变,我将尝试解释如何以一种简单的方式解决这类问题.
假设我们有一个模型(在应用程序中调用users),如下所示:
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
Run Code Online (Sandbox Code Playgroud)
但过了一段时间我们需要添加成员加入的日期.所以我们想要这个:
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()
Run Code Online (Sandbox Code Playgroud)
现在,通常你会遇到与OP写的相同的问题.要解决它,请按照下列步骤操作:
从这一点开始:
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
Run Code Online (Sandbox Code Playgroud)通过建立模型和运行python manage.py makemigrations(但不要把through财产在Group.members外地还没有):
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) # <-- no through property yet!
def __str__(self):
return self.name
class Membership(models.Model): # <--- through model
person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateField()
Run Code Online (Sandbox Code Playgroud)使用python manage.py makemigrations users --empty命令创建一个空迁移并在python中创建转换脚本(更多关于这里的python迁移),它Membership为旧字段(Group.members)创建新的relationship ().它可能看起来像这样:
# Generated by Django A.B on 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()
class Migration(migrations.Migration):
dependencies = [
('myapp', '0005_create_models'),
]
operations = [
migrations.RunPython(create_through_relations, reverse_code=migrations.RunPython.noop),
]
Run Code Online (Sandbox Code Playgroud)删除模型中的members字段Group并运行python manage.py makemigrations,因此我们Group将如下所示:
class Group(models.Model):
name = models.CharField(max_length=128)
Run Code Online (Sandbox Code Playgroud)添加members字段Group模型,但现在使用through属性并运行python manage.py makemigrations:
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
Run Code Online (Sandbox Code Playgroud)就是这样!现在,您需要在代码中以新的方式更改成员的创建 - 通过模型.更多关于这里.
小智 21
可能的解决方法:
创建一个名为ForeignKey关系的新字段,profiles1不要修改profiles.制作并运行迁移.您可能需要一个related_name参数来防止冲突.执行后续迁移以删除原始字段.然后做一次迁移一个重命名profiles1回profiles.显然,您不会在新的ForeignKey字段中包含数据.
编写自定义迁移:https://docs.djangoproject.com/en/1.7/ref/migration-operations/
您可能需要使用makemigration和migration,而不是syncdb.
您是否InstituteStaff拥有要保留的数据?
小智 16
如果您仍在开发应用程序,并且不需要保留现有数据,则可以通过执行以下操作来解决此问题:
删除并重新创建数据库.
转到您的项目/ app/migrations文件夹
删除该文件夹中的所有内容,但init .py文件除外.确保你也删除了pycache目录.
运行syncdb,makemigrations和migrate.
| 归档时间: |
|
| 查看次数: |
14805 次 |
| 最近记录: |