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
This commit is contained in:
Jacob Kaplan-Moss 2009-04-09 15:03:31 +00:00
parent f55f2b9d74
commit c0ad626dca
4 changed files with 55 additions and 6 deletions

View File

@ -140,7 +140,8 @@ class BaseDatabaseCreation(object):
"Return the CREATE TABLE statments for all the many-to-many tables defined on a model" "Return the CREATE TABLE statments for all the many-to-many tables defined on a model"
output = [] output = []
for f in model._meta.local_many_to_many: 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 return output
def sql_for_many_to_many_field(self, model, f, style): def sql_for_many_to_many_field(self, model, f, style):

View File

@ -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 specify all the columns from the database table you are modeling when
using unmanaged models. using unmanaged models.
2. If a model contains a :class:`~django.db.models.ManyToManyField` and 2. If a model with ``managed=False`` contains a
has ``managed=False``, the intermediate table for the many-to-many join :class:`~django.db.models.ManyToManyField` that points to another
will also not be created. Should you require the intermediate table to unmanaged model, then the intermediate table for the many-to-many join
be created, set it up as an explicit model and use the will also not be created. However, a the intermediary table between one
:attr:`ManyToManyField.through` attribute. 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 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. the correct tables are created as part of the test setup.

View File

@ -89,6 +89,27 @@ class Intermediate(models.Model):
db_table = 'D01' db_table = 'D01'
managed = False 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':""" __test__ = {'API_TESTS':"""
The main test here is that the all the models can be created without any 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 database errors. We can also do some more simple insertion and lookup tests

View File

@ -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)