This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.db import models | |
class Bar(models.Model): | |
spam = models.EmailField() | |
class Foo(models.Model): | |
bars = models.ManyToManyField(Bar) |
$ ./manage.py inspectdb through_foo_barsWe can make explicit the automatic relation that Django has created in the form of an extra table, by adding the model to our application.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.db import models | |
class Bar(models.Model): | |
spam = models.EmailField() | |
class Foo(models.Model): | |
bars = models.ManyToManyField(Bar, through='ThroughFooBars') | |
class ThroughFooBars(models.Model): | |
foo = models.ForeignKey(Foo, models.DO_NOTHING) | |
bar = models.ForeignKey(Bar, models.DO_NOTHING) | |
order = models.PositiveIntegerField(default=0) | |
class Meta: | |
db_table = 'through_foo_bars' | |
unique_together = (('foo', 'bar'),) | |
ordering = ('order',) |
$ ./manage.py makemigrationsThe problem starts when we try to execute the migrations
$ ./manage.py migrate ... ValueError: Cannot alter field through.Foo.bars into through.Foo.bars - they are not compatible types (you cannot alter to or from M2M fields, or add or remove through= on M2M fields)So according to Django this kind of migration is not possible. Let's analyse what the problem is. The below migration tries to create a new model called ThroughFooBars and then change the ManyToManyField on Foo.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Generated by Django 2.2 on 2019-04-22 11:25 | |
from django.db import migrations, models | |
class Migration(migrations.Migration): | |
dependencies = [ | |
('through', '0001_initial'), | |
] | |
operations = [ | |
migrations.CreateModel( | |
name='ThroughFooBars', | |
fields=[ | |
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |
('foo', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='through.Foo')), | |
('bar', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='through.Bar')), | |
('order', models.PositiveIntegerField(default=0)), | |
], | |
options={ | |
'db_table': 'through_foo_bars', | |
'unique_together': (('foo', 'bar'),), | |
'ordering': ('order',), | |
}, | |
), | |
migrations.AlterField( | |
model_name='foo', | |
name='bars', | |
field=models.ManyToManyField(through='through.ThroughFooBars', to='through.Bar'), | |
), | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Generated by Django 2.2 on 2019-04-22 12:38 | |
from django.db import migrations, models | |
class Migration(migrations.Migration): | |
dependencies = [ | |
('through', '0001_initial'), | |
] | |
state_operations = [ | |
migrations.CreateModel( | |
name='ThroughFooBars', | |
fields=[ | |
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |
('foo', models.ForeignKey(on_delete=models.deletion.CASCADE, to='through.Foo')), | |
('bar', models.ForeignKey(on_delete=models.deletion.CASCADE, to='through.Bar')), | |
], | |
options={ | |
'db_table': 'through_foo_bars', | |
'unique_together': (('foo', 'bar'),), | |
}, | |
), | |
migrations.AlterField( | |
model_name='foo', | |
name='bars', | |
field=models.ManyToManyField(through='through.ThroughFooBars', to='through.Bar'), | |
), | |
] | |
operations = [ | |
migrations.SeparateDatabaseAndState(state_operations=state_operations), | |
migrations.AddField( | |
model_name='throughfoobars', | |
name='order', | |
field=models.PositiveIntegerField(default=0), | |
), | |
migrations.AlterModelOptions( | |
name='throughfoobars', | |
options={'ordering': ('order',)}, | |
), | |
] |
$ ./manage.py inspectdb through_foo_bars
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.db import models | |
class ThroughFooBars(models.Model): | |
foo = models.ForeignKey('ThroughFoo', models.DO_NOTHING) | |
bar = models.ForeignKey('ThroughBar', models.DO_NOTHING) | |
order = models.PositiveIntegerField() | |
class Meta: | |
managed = False | |
db_table = 'through_foo_bars' | |
unique_together = (('foo', 'bar'),) |
Both migrations file are equal
ReplyDeleteI fixed it. github wont let you embed a different revision of a file than the latest :\
Delete