South migrations and changes to many-to-may fields

牧云@^-^@ 提交于 2019-12-11 07:32:01

问题


I was working on an app that is supposed to send newsletters to customers. I had a model defined like this

from django.auth.models import User

class Newsletter(models.Model):                                                                  
    owner = models.ForeignKey(User, related_name='+', blank=False)                                                                                                                                                  
    sent = models.BooleanField(default=False)                                                                                                                                                                       
    date_created = models.DateTimeField(auto_now_add=True)                                                                                                                                                          
    date_sent = models.DateTimeField(null=True)                                                                                                                                                                     
    subject = models.CharField(max_length=255)                                                                                                                                                                      
    content = HTMLField()                                                                                                                                                                                           
    recipients = models.ManyToManyField(User, related_name='+')                                                                                                                                                    

Later on, I found out that I might need to send these to people who do not have user accounts, so I defined an email model

class Email(models.Model):                                                                                                                                                                                          
    email = models.CharField(max_length=255)                                                          

and changed the recipients field to read

recipients = models.ManyToManyField(Email, related_name='+')

After this, I ran schemamigration command, but South claimed that there are no changes. I have made several attempts to manually manipulate tables and indexes, but at some point figured that since it is a new app, I can just drop all the existing tables, remove all igrations and recreate initial migration from scratch. This poses a question though, how do I do a migration like this if I really need to preserve the data.


回答1:


If you need to preserve data you will need to split it into 3 migrations (schema, data, schema) like this:

class Migration(SchemaMigration):

    def forwards(self, orm):
        db.add_column(
            u'yourapp_newsletter_recipients',
            'email_id',
            self.gf(
                'django.db.models.fields.related.ForeignKey'
            )(to=orm.Email)
        )

Notice that you should have your old schema in the migration's models property.

Then your data migration that fills the email field. Then schema migration again:

class Migration(SchemaMigration):

    def forwards(self, orm):
        db.delete_column(u'yourapp_newsletter_recipients', 'user_id')

In this one you should already have correct m2m field for recipients field in the migration's models['newslatter']



来源:https://stackoverflow.com/questions/13755119/south-migrations-and-changes-to-many-to-may-fields

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!