diff --git a/django/core/management/commands/inspectdb.py b/django/core/management/commands/inspectdb.py index 10fd9bd463..a524e64f65 100644 --- a/django/core/management/commands/inspectdb.py +++ b/django/core/management/commands/inspectdb.py @@ -26,6 +26,8 @@ class Command(NoArgsCommand): def handle_inspection(self, options): connection = connections[options.get('database')] + # 'table_name_filter' is a stealth option + table_name_filter = options.get('table_name_filter') table2model = lambda table_name: table_name.title().replace('_', '').replace(' ', '').replace('-', '') @@ -43,6 +45,9 @@ class Command(NoArgsCommand): yield '' known_models = [] for table_name in connection.introspection.table_names(cursor): + if table_name_filter is not None and callable(table_name_filter): + if not table_name_filter(table_name): + continue yield 'class %s(models.Model):' % table2model(table_name) known_models.append(table2model(table_name)) try: diff --git a/tests/regressiontests/inspectdb/tests.py b/tests/regressiontests/inspectdb/tests.py index 6896bf9126..8d1222c545 100644 --- a/tests/regressiontests/inspectdb/tests.py +++ b/tests/regressiontests/inspectdb/tests.py @@ -6,10 +6,31 @@ from django.test import TestCase, skipUnlessDBFeature class InspectDBTestCase(TestCase): + def test_stealth_table_name_filter_option(self): + out = StringIO() + # Lets limit the introspection to tables created for models of this + # application + call_command('inspectdb', + table_name_filter=lambda tn:tn.startswith('inspectdb_'), + stdout=out) + error_message = "inspectdb has examined a table that should have been filtered out." + # contrib.contenttypes is one of the apps always installed when running + # the Django test suite, check that one of its tables hasn't been + # inspected + self.assertNotIn("class DjangoContentType(models.Model):", out.getvalue(), msg=error_message) + out.close() + @skipUnlessDBFeature('can_introspect_foreign_keys') def test_attribute_name_not_python_keyword(self): out = StringIO() - call_command('inspectdb', stdout=out) + # Lets limit the introspection to tables created for models of this + # application + call_command('inspectdb', + table_name_filter=lambda tn:tn.startswith('inspectdb_'), + stdout=out) + f = open('/home/ramiro/models2.py', 'w') + f.write(out.getvalue()) + f.close() error_message = "inspectdb generated an attribute name which is a python keyword" self.assertNotIn("from = models.ForeignKey(InspectdbPeople)", out.getvalue(), msg=error_message) # As InspectdbPeople model is defined after InspectdbMessage, it should be quoted @@ -23,7 +44,11 @@ class InspectDBTestCase(TestCase): def test_digits_column_name_introspection(self): """Introspection of column names consist/start with digits (#16536/#17676)""" out = StringIO() - call_command('inspectdb', stdout=out) + # Lets limit the introspection to tables created for models of this + # application + call_command('inspectdb', + table_name_filter=lambda tn:tn.startswith('inspectdb_'), + stdout=out) error_message = "inspectdb generated a model field name which is a number" self.assertNotIn(" 123 = models.CharField", out.getvalue(), msg=error_message) self.assertIn("number_123 = models.CharField", out.getvalue())