From e960faf4195027787fd653dad3914f729a5e06ee Mon Sep 17 00:00:00 2001
From: Simon Charette <charette.s@gmail.com>
Date: Sun, 27 Jan 2013 23:31:29 -0500
Subject: [PATCH] Fixed #19677 -- Create inline references for recursive fks
---
django/db/backends/creation.py | 11 ++++++-----
django/db/backends/mysql/creation.py | 2 +-
tests/regressiontests/introspection/models.py | 1 +
tests/regressiontests/introspection/tests.py | 6 ++++--
4 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/django/db/backends/creation.py b/django/db/backends/creation.py
index 2baed62..7304ebb 100644
a
|
b
|
class BaseDatabaseCreation(object):
|
77 | 77 | field_output.append(tablespace_sql) |
78 | 78 | if f.rel: |
79 | 79 | ref_output, pending = self.sql_for_inline_foreign_key_references( |
80 | | f, known_models, style) |
| 80 | model, f, known_models, style) |
81 | 81 | if pending: |
82 | 82 | pending_references.setdefault(f.rel.to, []).append( |
83 | 83 | (model, f)) |
… |
… |
class BaseDatabaseCreation(object):
|
116 | 116 | |
117 | 117 | return final_output, pending_references |
118 | 118 | |
119 | | def sql_for_inline_foreign_key_references(self, field, known_models, style): |
| 119 | def sql_for_inline_foreign_key_references(self, model, field, known_models, style): |
120 | 120 | """ |
121 | 121 | Return the SQL snippet defining the foreign key reference for a field. |
122 | 122 | """ |
123 | 123 | qn = self.connection.ops.quote_name |
124 | | if field.rel.to in known_models: |
| 124 | rel_to = field.rel.to |
| 125 | if rel_to in known_models or rel_to == model: |
125 | 126 | output = [style.SQL_KEYWORD('REFERENCES') + ' ' + |
126 | | style.SQL_TABLE(qn(field.rel.to._meta.db_table)) + ' (' + |
127 | | style.SQL_FIELD(qn(field.rel.to._meta.get_field( |
| 127 | style.SQL_TABLE(qn(rel_to._meta.db_table)) + ' (' + |
| 128 | style.SQL_FIELD(qn(rel_to._meta.get_field( |
128 | 129 | field.rel.field_name).column)) + ')' + |
129 | 130 | self.connection.ops.deferrable_sql() |
130 | 131 | ] |
diff --git a/django/db/backends/mysql/creation.py b/django/db/backends/mysql/creation.py
index 53bd57e..eb31dc6 100644
a
|
b
|
class DatabaseCreation(BaseDatabaseCreation):
|
38 | 38 | suffix.append('COLLATE %s' % self.connection.settings_dict['TEST_COLLATION']) |
39 | 39 | return ' '.join(suffix) |
40 | 40 | |
41 | | def sql_for_inline_foreign_key_references(self, field, known_models, style): |
| 41 | def sql_for_inline_foreign_key_references(self, model, field, known_models, style): |
42 | 42 | "All inline references are pending under MySQL" |
43 | 43 | return [], True |
44 | 44 | |
diff --git a/tests/regressiontests/introspection/models.py b/tests/regressiontests/introspection/models.py
index 4de82e4..cfa72c9 100644
a
|
b
|
class Article(models.Model):
|
23 | 23 | headline = models.CharField(max_length=100) |
24 | 24 | pub_date = models.DateField() |
25 | 25 | reporter = models.ForeignKey(Reporter) |
| 26 | response_to = models.ForeignKey('self', null=True) |
26 | 27 | |
27 | 28 | def __str__(self): |
28 | 29 | return self.headline |
diff --git a/tests/regressiontests/introspection/tests.py b/tests/regressiontests/introspection/tests.py
index cd3e1cc..91d1a88 100644
a
|
b
|
class IntrospectionTests(TestCase):
|
106 | 106 | # should test that the response is correct. |
107 | 107 | if relations: |
108 | 108 | # That's {field_index: (field_index_other_table, other_table)} |
109 | | self.assertEqual(relations, {3: (0, Reporter._meta.db_table)}) |
| 109 | self.assertEqual(relations, {3: (0, Reporter._meta.db_table), |
| 110 | 4: (0, Article._meta.db_table)}) |
110 | 111 | |
111 | 112 | @skipUnlessDBFeature('can_introspect_foreign_keys') |
112 | 113 | def test_get_key_columns(self): |
113 | 114 | cursor = connection.cursor() |
114 | 115 | key_columns = connection.introspection.get_key_columns(cursor, Article._meta.db_table) |
115 | | self.assertEqual(key_columns, [('reporter_id', Reporter._meta.db_table, 'id')]) |
| 116 | self.assertEqual(key_columns, [('reporter_id', Reporter._meta.db_table, 'id'), |
| 117 | ('response_to_id', Article._meta.db_table, 'id')]) |
116 | 118 | |
117 | 119 | def test_get_primary_key_column(self): |
118 | 120 | cursor = connection.cursor() |