Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #10647: intermediary tables between two umanaged models are no …

…longer created.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@10455 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit c0ad626dca67fe2e0c1dce3c5db524cfa77a9884 1 parent f55f2b9
@jacobian jacobian authored
View
3  django/db/backends/creation.py
@@ -140,7 +140,8 @@ def sql_for_many_to_many(self, model, style):
"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:
- output.extend(self.sql_for_many_to_many_field(model, f, style))
+ if model._meta.managed or f.rel.to._meta.managed:
+ output.extend(self.sql_for_many_to_many_field(model, f, style))
return output
def sql_for_many_to_many_field(self, model, f, style):
View
15 docs/ref/models/options.txt
@@ -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.
View
21 tests/modeltests/unmanaged_models/models.py
@@ -89,6 +89,27 @@ class Meta:
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
View
22 tests/modeltests/unmanaged_models/tests.py
@@ -0,0 +1,22 @@
+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)
+
Please sign in to comment.
Something went wrong with that request. Please try again.