如何将数据从ManyToManyField迁移到ForeignKey?

时间:2014-05-20 15:48:57

标签: django django-south data-migration

我想将数据从ManyToMany-Field迁移到ForeignKey-Field。由于我在之前的迁移中将数据迁移到另一个方向(从ForeignKey迁移到ManyToMany)并且将在一个步骤中部署这两个迁移,我想这应该可行。

我有这个模型:

class Log(models.Model):
    contacts = models.ManyToManyField(Contact, related_name='contact_logs', blank=True, null=True)

我添加了新字段:

class Log(models.Model):
    contact = models.ForeignKey(Contact, blank=True, null=True)
    contacts = models.ManyToManyField(Contact, related_name='contact_logs', blank=True, null=True)

然后我做了:

$ ./manage.py schemamigration myapp --auto
$ ./manage.py datamigration myapp move_contacts_data

现在我尝试编写数据迁移。这就是我以前的方式 将数据从ForeignKey迁移到ManyToMany:

def forwards(self, orm):
   "Write your forwards methods here."
   for log in orm.Log.objects.all():
       if log.contacts:
           log.contact.add(log.contacts)
           log.save()

但这似乎并没有相反的方式。我明白了:

$ ./manage.py migrate myapp                                   :(
Running migrations for myapp:
- Migrating forwards to 0072_move_contacts_data.
contacts:0072_move_contacts_data
Error in migration: myapp:0072_move_contacts_data
AttributeError: 'NoneType' object has no attribute 'add'

有人可以帮帮我吗?

2 个答案:

答案 0 :(得分:0)

如果您的m2m关系仅包含每个日志的单个联系人,则可以执行以下操作:

def forwards(self, orm):
   "Write your forwards methods here."
   for log in orm.Log.objects.all():
       if log.contacts.all():
           assert log.contacts.count() == 1
           log.contact = log.contacts.get()
           log.save()

如果关系包含多个联系人,则必须定义一种方法来确定要保存的联系人。这可以是某个任意日期字段或任何其他字段。无论哪种方式,您都会丢失一些数据。如何处理这取决于你。

答案 1 :(得分:0)

你的想法是对的,你只是添加数据错误 - 联系 - ForeignKey现在,所以你需要像这样添加:

def forwards(self, orm):
   "Write your forwards methods here."
   for log in orm.Log.objects.all():
       if log.contacts:
           log.contact = orm.Contact.objects.create(...some data from contacts...) 
           log.save()