Monday, September 28, 2015

Converting implicit m2m through table to explicit through model with Django 1.7 migrations

Hi all,

I'm attempting to convert an implicit m2m through table to an explicit through model and want to make sure I'm not shooting myself in the foot. Any input would be greatly appreciated.

My team was on Django 1.6 until a few months ago and was still living in the South world. We had a need to take an implicit through table for a m2m field and convert it to an explicit through model so we could add some extra data to it. 

To do so we:
1) Created the new model and set db_table on the model's Meta to the existing implicit through table and setup the model's fields accordingly.
2) Created the south migration. There were no database changes since everything lined up.
3) Added the additional fields to the new through model.
4) Created another south migration.
5) Ran the migrations.

This worked well - we were able to convert the implicit through to an explicit through and add extra fields while retaining our data.

I'm now trying to do the same thing in the world of Django 1.7 migrations. The same process works, but when I run the migration created in step 2 it fails because the table already exists. To get around this, I'm experimenting with using migrations.SeparateDatabaseAndState. Since these are purely state changes, it seemed reasonable to move all of the operations created by the migration in step 2 to a list of state_operations. This works! Nothing blows up and I'm able to add the fields as needed.

However, I'm concerned this might have repercussions down the line. I've also experimented with keeping the model creation portion of the migration as state operations, but moving the field alterations on the m2ms to the top level operations list. This blows up with the following error: "you cannot alter to or from M2M fields, or add or remove through= on M2M fields." My understanding is that M2M field changes are disallowed because it's difficult for the migrations to know what to do. Accordingly, I'm worried I could be hacking myself into a corner.

So - is my approach safe? Or will there be complications down the line?

Thank you,

You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
To post to this group, send email to
Visit this group at
To view this discussion on the web visit
For more options, visit

No comments:

Post a Comment