Django: convert ManyToManyField to ForeignKey
django, django-models, python
Solution
This is nontrivial, I think you will need three migrations:
- Add the `ForeignKey`.
- Convert the `ManyToMany` to `ForeignKey` (using the `forwards` method).
- Remove the `ManyToMany`.
You could possibly merge 1 and 2 or 2 and 3 together, but I wouldn't recommend it. Additionally, you should also implement a `backwards` method for 2.
An example for 2.'s `forwards` would be:
class Migration(SchemaMigration):
def forwards(self, orm):
for manufacturer in orm.Manufacturer.objects.all():
for car in manufacturer.car.all():
car.manufacturer = manufacturer
car.save()
Please note that:
- There is no `backwards` method here yet.
- This needs to be tested extensively: a migration is something you should be extra careful about.
- In case a car has two manufacturers, the last one will be kept.
- This is very inefficient, we do a Query per car per manufacturer!
You will also need to update the code that uses those relationships in step 2. / 3.
Problem
Let's supposed I created two models: ``` class Car(models.Model): name = models.CharField(max_length=50) size = models.IntegerField() class Manufacturer(models.Model): name = models.CharField(max_length=50) country = models.CharField(max_length=50) car = models.ManyToManyField(Car) ``` I added entries to both models, then I realized that each Car was only related to a unique Manufacturer. So, I should convert my ManyToManyField to a ForeignKey: ``` class Car(models.Model): name = models.CharField(max_length=50) size = models.IntegerField() manufacturer = models.ForeignKey(Manufacturer) class Manufacturer(models.Model): name = models.CharField(max_length=50) country = models.CharField(max_length=50) ``` How can I do that without losing my entries? I tried to look in South documentation but I did not found this way of conversion...