Loading django/db/backends/creation.py +2 −1 Original line number Diff line number Diff line Loading @@ -140,6 +140,7 @@ class BaseDatabaseCreation(object): "Return the CREATE TABLE statments for all the many-to-many tables defined on a model" output = [] for f in model._meta.local_many_to_many: if model._meta.managed or f.rel.to._meta.managed: output.extend(self.sql_for_many_to_many_field(model, f, style)) return output Loading docs/ref/models/options.txt +10 −5 Original line number Diff line number Diff line Loading @@ -98,11 +98,16 @@ model handling are exactly the same as normal. This includes specify all the columns from the database table you are modeling when using unmanaged models. 2. If a model contains a :class:`~django.db.models.ManyToManyField` and has ``managed=False``, the intermediate table for the many-to-many join will also not be created. Should you require the intermediate table to be created, set it up as an explicit model and use the :attr:`ManyToManyField.through` attribute. 2. If a model with ``managed=False`` contains a :class:`~django.db.models.ManyToManyField` that points to another unmanaged model, then the intermediate table for the many-to-many join will also not be created. However, a the intermediary table between one managed and one unmanaged model *will* be created. If you need to change this default behavior, create the intermediary table as an explicit model (with ``managed`` set as needed) and use the :attr:`ManyToManyField.through` attribute to make the relation use your custom model. For tests involving models with ``managed=False``, it's up to you to ensure the correct tables are created as part of the test setup. Loading tests/modeltests/unmanaged_models/models.py +21 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,27 @@ class Intermediate(models.Model): db_table = 'D01' managed = False # # These next models test the creation (or not) of many to many join tables # between managed and unmanaged models. A join table between two unmanaged # models shouldn't be automatically created (see #10647). # class Unmanaged1(models.Model): class Meta: managed = False # Unmanged with an m2m to unmanaged: the intermediary table won't be created. class Unmanaged2(models.Model): mm = models.ManyToManyField(Unmanaged1) class Meta: managed = False # Here's an unmanaged model with an m2m to a managed one; the intermediary # table *will* be created (unless given a custom `through` as for C02 above). class Managed1(models.Model): mm = models.ManyToManyField(Unmanaged1) __test__ = {'API_TESTS':""" The main test here is that the all the models can be created without any database errors. We can also do some more simple insertion and lookup tests Loading tests/modeltests/unmanaged_models/tests.py 0 → 100644 +22 −0 Original line number Diff line number Diff line from django.test import TestCase from django.db import connection from models import Unmanaged1, Unmanaged2, Managed1 class ManyToManyUnmanagedTests(TestCase): def test_many_to_many_between_unmanaged(self): """ The intermediary table between two unmanaged models should not be created. """ table = Unmanaged2._meta.get_field('mm').m2m_db_table() tables = connection.introspection.table_names() self.assert_(table not in tables, "Table '%s' should not exist, but it does." % table) def test_many_to_many_between_unmanaged_and_managed(self): """ An intermediary table between a managed and an unmanaged model should be created. """ table = Managed1._meta.get_field('mm').m2m_db_table() tables = connection.introspection.table_names() self.assert_(table in tables, "Table '%s' does not exist." % table) No newline at end of file Loading
django/db/backends/creation.py +2 −1 Original line number Diff line number Diff line Loading @@ -140,6 +140,7 @@ class BaseDatabaseCreation(object): "Return the CREATE TABLE statments for all the many-to-many tables defined on a model" output = [] for f in model._meta.local_many_to_many: if model._meta.managed or f.rel.to._meta.managed: output.extend(self.sql_for_many_to_many_field(model, f, style)) return output Loading
docs/ref/models/options.txt +10 −5 Original line number Diff line number Diff line Loading @@ -98,11 +98,16 @@ model handling are exactly the same as normal. This includes specify all the columns from the database table you are modeling when using unmanaged models. 2. If a model contains a :class:`~django.db.models.ManyToManyField` and has ``managed=False``, the intermediate table for the many-to-many join will also not be created. Should you require the intermediate table to be created, set it up as an explicit model and use the :attr:`ManyToManyField.through` attribute. 2. If a model with ``managed=False`` contains a :class:`~django.db.models.ManyToManyField` that points to another unmanaged model, then the intermediate table for the many-to-many join will also not be created. However, a the intermediary table between one managed and one unmanaged model *will* be created. If you need to change this default behavior, create the intermediary table as an explicit model (with ``managed`` set as needed) and use the :attr:`ManyToManyField.through` attribute to make the relation use your custom model. For tests involving models with ``managed=False``, it's up to you to ensure the correct tables are created as part of the test setup. Loading
tests/modeltests/unmanaged_models/models.py +21 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,27 @@ class Intermediate(models.Model): db_table = 'D01' managed = False # # These next models test the creation (or not) of many to many join tables # between managed and unmanaged models. A join table between two unmanaged # models shouldn't be automatically created (see #10647). # class Unmanaged1(models.Model): class Meta: managed = False # Unmanged with an m2m to unmanaged: the intermediary table won't be created. class Unmanaged2(models.Model): mm = models.ManyToManyField(Unmanaged1) class Meta: managed = False # Here's an unmanaged model with an m2m to a managed one; the intermediary # table *will* be created (unless given a custom `through` as for C02 above). class Managed1(models.Model): mm = models.ManyToManyField(Unmanaged1) __test__ = {'API_TESTS':""" The main test here is that the all the models can be created without any database errors. We can also do some more simple insertion and lookup tests Loading
tests/modeltests/unmanaged_models/tests.py 0 → 100644 +22 −0 Original line number Diff line number Diff line from django.test import TestCase from django.db import connection from models import Unmanaged1, Unmanaged2, Managed1 class ManyToManyUnmanagedTests(TestCase): def test_many_to_many_between_unmanaged(self): """ The intermediary table between two unmanaged models should not be created. """ table = Unmanaged2._meta.get_field('mm').m2m_db_table() tables = connection.introspection.table_names() self.assert_(table not in tables, "Table '%s' should not exist, but it does." % table) def test_many_to_many_between_unmanaged_and_managed(self): """ An intermediary table between a managed and an unmanaged model should be created. """ table = Managed1._meta.get_field('mm').m2m_db_table() tables = connection.introspection.table_names() self.assert_(table in tables, "Table '%s' does not exist." % table) No newline at end of file