I have a problem where South is not persisting the on_delete option
passed to a ForeignKey, when it saves the ORM into a migration.
The default behaviour of ForeignKey is a Cascade Delete, whereas my
models are specifying on_delete=models.SET_NULL, asking Django to
avoid the default behaviour in this case, and keep the related models.
In my specific case, I've a data migration creating some rows and
adding references to them from an existing table, so when the reverse
migration deletes the rows it creates, it's deleting all the related
rows. A large chunk of my database disappears up in smoke, so this is
a pretty serious bug :-)
To illustrate this here are two simple models:
*** models.py
from django.db import models
class RelationA(models.Model):
pass
class RelationB(models.Model):
a = models.ForeignKey(RelationA, null=True, blank=True,
on_delete=models.SET_NULL)
***
And here are some tests (I created a migration to use in the test,
with --initial, but any migration created on those models would be the
same): the django_test passes, the south version fails.
*** test.py
from django.test import TestCase
import models as django_models
from south.migration.base import Migrations
class NoCascadeDeleteTest(TestCase):
def test_south(self):
mm = Migrations('experiment')
migration = mm[0]
self._test(migration.orm())
def test_django(self):
self._test(django_models)
def _test(self, orm):
a = orm.RelationA()
a.save()
b = orm.RelationB()
b.a = a
b.save()
self.assertEqual(orm.RelationA.objects.all().count(), 1, "Test
setup failed - expected 1 entry in each table")
self.assertEqual(orm.RelationB.objects.all().count(), 1, "Test
setup failed - expected 1 entry in each table")
orm.RelationA.objects.all().delete()
self.assertEqual(orm.RelationA.objects.all().count(), 0,
"RelationA not cleared for some reason.")
self.assertEqual(orm.RelationB.objects.all().count(), 1, "The
test failed: cascade delete happened.")
***
Having decided that this is a bug in South, I don't mind having a go
at finding a fix, but being quite new I'd appreciate some confirmation
before I get stuck in.
thanks
George