diff --git a/django/core/management/commands/inspectdb.py b/django/core/management/commands/inspectdb.py index c3c0776273..936d5e89ab 100644 --- a/django/core/management/commands/inspectdb.py +++ b/django/core/management/commands/inspectdb.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals import keyword +import re from optparse import make_option from django.core.management.base import NoArgsCommand, CommandError @@ -142,18 +143,16 @@ class Command(NoArgsCommand): else: field_params['db_column'] = col_name - if ' ' in new_name: - new_name = new_name.replace(' ', '_') - field_notes.append('Field renamed to remove spaces.') - - if '-' in new_name: - new_name = new_name.replace('-', '_') - field_notes.append('Field renamed to remove dashes.') + new_name, num_repl = re.subn(r'\W', '_', new_name) + if num_repl > 0: + field_notes.append('Field renamed to remove unsuitable characters.') if new_name.find('__') >= 0: while new_name.find('__') >= 0: new_name = new_name.replace('__', '_') - field_notes.append("Field renamed because it contained more than one '_' in a row.") + if col_name.lower().find('__') >= 0: + # Only add the comment if the double underscore was in the original name + field_notes.append("Field renamed because it contained more than one '_' in a row.") if new_name.startswith('_'): new_name = 'field%s' % new_name diff --git a/tests/regressiontests/inspectdb/models.py b/tests/regressiontests/inspectdb/models.py index 352053aafe..4a6621402f 100644 --- a/tests/regressiontests/inspectdb/models.py +++ b/tests/regressiontests/inspectdb/models.py @@ -20,8 +20,11 @@ class DigitsInColumnName(models.Model): leading_digit = models.CharField(max_length=11, db_column='4extra') leading_digits = models.CharField(max_length=11, db_column='45extra') -class UnderscoresInColumnName(models.Model): +class SpecialColumnName(models.Model): field = models.IntegerField(db_column='field') + # Underscores field_field_0 = models.IntegerField(db_column='Field_') field_field_1 = models.IntegerField(db_column='Field__') field_field_2 = models.IntegerField(db_column='__field') + # Other chars + prc_x = models.IntegerField(db_column='prc(%) x') diff --git a/tests/regressiontests/inspectdb/tests.py b/tests/regressiontests/inspectdb/tests.py index b5647e9e38..484e7f4060 100644 --- a/tests/regressiontests/inspectdb/tests.py +++ b/tests/regressiontests/inspectdb/tests.py @@ -59,8 +59,10 @@ class InspectDBTestCase(TestCase): self.assertNotIn(" 45extra = models.CharField", output, msg=error_message) self.assertIn("number_45extra = models.CharField", output) - def test_underscores_column_name_introspection(self): - """Introspection of column names containing underscores (#12460)""" + def test_special_column_name_introspection(self): + """Introspection of column names containing special characters, + unsuitable for Python identifiers + """ out = StringIO() call_command('inspectdb', stdout=out) output = out.getvalue() @@ -68,3 +70,4 @@ class InspectDBTestCase(TestCase): self.assertIn("field_field = models.IntegerField(db_column='Field_')", output) self.assertIn("field_field_0 = models.IntegerField(db_column='Field__')", output) self.assertIn("field_field_1 = models.IntegerField(db_column='__field')", output) + self.assertIn("prc_x = models.IntegerField(db_column='prc(%) x')", output)