From 52bc78262172ad6e8deb3c75bd65edea68924dbc Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Sat, 11 Jul 2009 14:22:52 +0000 Subject: [PATCH] Fixed #11107 -- Corrected the generation of sequence reset SQL for m2m fields with an intermediate model. Thanks to J Clifford Dyer for the report and fix. git-svn-id: http://code.djangoproject.com/svn/django/trunk@11215 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- AUTHORS | 1 + django/db/backends/oracle/base.py | 13 +++---- django/db/backends/postgresql/operations.py | 17 +++++----- .../fixtures/m2m_through.json | 34 +++++++++++++++++++ .../m2m_through_regress/models.py | 10 ++++++ 5 files changed, 61 insertions(+), 14 deletions(-) create mode 100644 tests/regressiontests/m2m_through_regress/fixtures/m2m_through.json diff --git a/AUTHORS b/AUTHORS index 5f36d83770..c965ddee4e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -131,6 +131,7 @@ answer newbie questions, and generally made Django that much better: Andrew Durdin dusk@woofle.net Andy Dustman + J. Clifford Dyer Clint Ecker Nick Efford eibaan@gmail.com diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 8f96049cc4..7d85979294 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -217,12 +217,13 @@ WHEN (new.%(col_name)s IS NULL) # continue to loop break for f in model._meta.many_to_many: - table_name = self.quote_name(f.m2m_db_table()) - sequence_name = get_sequence_name(f.m2m_db_table()) - column_name = self.quote_name('id') - output.append(query % {'sequence': sequence_name, - 'table': table_name, - 'column': column_name}) + if not f.rel.through: + table_name = self.quote_name(f.m2m_db_table()) + sequence_name = get_sequence_name(f.m2m_db_table()) + column_name = self.quote_name('id') + output.append(query % {'sequence': sequence_name, + 'table': table_name, + 'column': column_name}) return output def start_transaction_sql(self): diff --git a/django/db/backends/postgresql/operations.py b/django/db/backends/postgresql/operations.py index ee74be1624..331156ee11 100644 --- a/django/db/backends/postgresql/operations.py +++ b/django/db/backends/postgresql/operations.py @@ -121,14 +121,15 @@ class DatabaseOperations(BaseDatabaseOperations): style.SQL_TABLE(qn(model._meta.db_table)))) break # Only one AutoField is allowed per model, so don't bother continuing. for f in model._meta.many_to_many: - output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ - (style.SQL_KEYWORD('SELECT'), - style.SQL_FIELD(qn('%s_id_seq' % f.m2m_db_table())), - style.SQL_FIELD(qn('id')), - style.SQL_FIELD(qn('id')), - style.SQL_KEYWORD('IS NOT'), - style.SQL_KEYWORD('FROM'), - style.SQL_TABLE(qn(f.m2m_db_table())))) + if not f.rel.through: + output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ + (style.SQL_KEYWORD('SELECT'), + style.SQL_FIELD(qn('%s_id_seq' % f.m2m_db_table())), + style.SQL_FIELD(qn('id')), + style.SQL_FIELD(qn('id')), + style.SQL_KEYWORD('IS NOT'), + style.SQL_KEYWORD('FROM'), + style.SQL_TABLE(qn(f.m2m_db_table())))) return output def savepoint_create_sql(self, sid): diff --git a/tests/regressiontests/m2m_through_regress/fixtures/m2m_through.json b/tests/regressiontests/m2m_through_regress/fixtures/m2m_through.json new file mode 100644 index 0000000000..6f24886f02 --- /dev/null +++ b/tests/regressiontests/m2m_through_regress/fixtures/m2m_through.json @@ -0,0 +1,34 @@ +[ + { + "pk": "1", + "model": "m2m_through_regress.person", + "fields": { + "name": "Guido" + } + }, + { + "pk": "1", + "model": "auth.user", + "fields": { + "username": "Guido", + "email": "bdfl@python.org", + "password": "abcde" + } + }, + { + "pk": "1", + "model": "m2m_through_regress.group", + "fields": { + "name": "Python Core Group" + } + }, + { + "pk": "1", + "model": "m2m_through_regress.usermembership", + "fields": { + "user": "1", + "group": "1", + "price": "100" + } + } +] \ No newline at end of file diff --git a/tests/regressiontests/m2m_through_regress/models.py b/tests/regressiontests/m2m_through_regress/models.py index 8594f19dee..dcf5f8115b 100644 --- a/tests/regressiontests/m2m_through_regress/models.py +++ b/tests/regressiontests/m2m_through_regress/models.py @@ -12,7 +12,9 @@ class Membership(models.Model): def __unicode__(self): return "%s is a member of %s" % (self.person.name, self.group.name) +# using custom id column to test ticket #11107 class UserMembership(models.Model): + id = models.AutoField(db_column='usermembership_id', primary_key=True) user = models.ForeignKey(User) group = models.ForeignKey('Group') price = models.IntegerField(default=100) @@ -196,4 +198,12 @@ doing a join. # Flush the database, just to make sure we can. >>> management.call_command('flush', verbosity=0, interactive=False) +## Regression test for #11107 +Ensure that sequences on m2m_through tables are being created for the through +model, not for a phantom auto-generated m2m table. + +>>> management.call_command('loaddata', 'm2m_through', verbosity=0) +>>> management.call_command('dumpdata', 'm2m_through_regress', format='json') +[{"pk": 1, "model": "m2m_through_regress.usermembership", "fields": {"price": 100, "group": 1, "user": 1}}, {"pk": 1, "model": "m2m_through_regress.person", "fields": {"name": "Guido"}}, {"pk": 1, "model": "m2m_through_regress.group", "fields": {"name": "Python Core Group"}}] + """}