diff --git a/django/db/backends/base/features.py b/django/db/backends/base/features.py index 10bd4077dcb..3f5a10b25a8 100644 --- a/django/db/backends/base/features.py +++ b/django/db/backends/base/features.py @@ -133,8 +133,10 @@ class BaseDatabaseFeatures: 'BigIntegerField': 'BigIntegerField', 'BinaryField': 'BinaryField', 'BooleanField': 'BooleanField', + 'CharField': 'CharField', 'DurationField': 'DurationField', 'GenericIPAddressField': 'GenericIPAddressField', + 'IntegerField': 'IntegerField', 'PositiveBigIntegerField': 'PositiveBigIntegerField', 'PositiveIntegerField': 'PositiveIntegerField', 'PositiveSmallIntegerField': 'PositiveSmallIntegerField', diff --git a/tests/inspectdb/tests.py b/tests/inspectdb/tests.py index 583512cc092..83326e96c0c 100644 --- a/tests/inspectdb/tests.py +++ b/tests/inspectdb/tests.py @@ -61,10 +61,10 @@ class InspectDBTestCase(TestCase): """Test introspection of various Django field types""" assertFieldType = self.make_field_type_asserter() introspected_field_types = connection.features.introspected_field_types - + char_field_type = introspected_field_types['CharField'] # Inspecting Oracle DB doesn't produce correct results (#19884): # - it reports fields as blank=True when they aren't. - if not connection.features.interprets_empty_strings_as_nulls: + if not connection.features.interprets_empty_strings_as_nulls and char_field_type == 'CharField': assertFieldType('char_field', "models.CharField(max_length=10)") assertFieldType('null_char_field', "models.CharField(max_length=10, blank=True, null=True)") assertFieldType('email_field', "models.CharField(max_length=254)") @@ -73,6 +73,15 @@ class InspectDBTestCase(TestCase): assertFieldType('slug_field', "models.CharField(max_length=50)") assertFieldType('text_field', "models.TextField()") assertFieldType('url_field', "models.CharField(max_length=200)") + if char_field_type == 'TextField': + assertFieldType('char_field', 'models.TextField()') + assertFieldType('null_char_field', 'models.TextField(blank=True, null=True)') + assertFieldType('email_field', 'models.TextField()') + assertFieldType('file_field', 'models.TextField()') + assertFieldType('file_path_field', 'models.TextField()') + assertFieldType('slug_field', 'models.TextField()') + assertFieldType('text_field', 'models.TextField()') + assertFieldType('url_field', 'models.TextField()') assertFieldType('date_field', "models.DateField()") assertFieldType('date_time_field', "models.DateTimeField()") if introspected_field_types['GenericIPAddressField'] == 'GenericIPAddressField': @@ -117,7 +126,7 @@ class InspectDBTestCase(TestCase): "as this database handles decimal fields as float") assertFieldType('float_field', "models.FloatField()") - assertFieldType('int_field', "models.IntegerField()") + assertFieldType('int_field', 'models.%s()' % introspected_field_types['IntegerField']) assertFieldType('pos_int_field', 'models.%s()' % introspected_field_types['PositiveIntegerField']) assertFieldType('pos_big_int_field', 'models.%s()' % introspected_field_types['PositiveBigIntegerField']) assertFieldType('pos_small_int_field', 'models.%s()' % introspected_field_types['PositiveSmallIntegerField']) @@ -152,19 +161,20 @@ class InspectDBTestCase(TestCase): def test_digits_column_name_introspection(self): """Introspection of column names consist/start with digits (#16536/#17676)""" + char_field_type = connection.features.introspected_field_types['CharField'] out = StringIO() call_command('inspectdb', 'inspectdb_digitsincolumnname', stdout=out) output = out.getvalue() error_message = "inspectdb generated a model field name which is a number" - self.assertNotIn(" 123 = models.CharField", output, msg=error_message) - self.assertIn("number_123 = models.CharField", output) + self.assertNotIn(' 123 = models.%s' % char_field_type, output, msg=error_message) + self.assertIn('number_123 = models.%s' % char_field_type, output) error_message = "inspectdb generated a model field name which starts with a digit" - self.assertNotIn(" 4extra = models.CharField", output, msg=error_message) - self.assertIn("number_4extra = models.CharField", output) + self.assertNotIn(' 4extra = models.%s' % char_field_type, output, msg=error_message) + self.assertIn('number_4extra = models.%s' % char_field_type, output) - self.assertNotIn(" 45extra = models.CharField", output, msg=error_message) - self.assertIn("number_45extra = models.CharField", output) + self.assertNotIn(' 45extra = models.%s' % char_field_type, output, msg=error_message) + self.assertIn('number_45extra = models.%s' % char_field_type, output) def test_special_column_name_introspection(self): """ @@ -175,12 +185,13 @@ class InspectDBTestCase(TestCase): call_command('inspectdb', table_name_filter=special_table_only, stdout=out) output = out.getvalue() base_name = connection.introspection.identifier_converter('Field') - self.assertIn("field = models.IntegerField()", output) - self.assertIn("field_field = models.IntegerField(db_column='%s_')" % base_name, output) - self.assertIn("field_field_0 = models.IntegerField(db_column='%s__')" % base_name, output) - self.assertIn("field_field_1 = models.IntegerField(db_column='__field')", output) - self.assertIn("prc_x = models.IntegerField(db_column='prc(%) x')", output) - self.assertIn("tamaño = models.IntegerField()", output) + integer_field_type = connection.features.introspected_field_types['IntegerField'] + self.assertIn("field = models.%s()" % integer_field_type, output) + self.assertIn("field_field = models.%s(db_column='%s_')" % (integer_field_type, base_name), output) + self.assertIn("field_field_0 = models.%s(db_column='%s__')" % (integer_field_type, base_name), output) + self.assertIn("field_field_1 = models.%s(db_column='__field')" % integer_field_type, output) + self.assertIn("prc_x = models.{}(db_column='prc(%) x')".format(integer_field_type), output) + self.assertIn("tamaño = models.%s()" % integer_field_type, output) def test_table_name_introspection(self): """ diff --git a/tests/introspection/tests.py b/tests/introspection/tests.py index 9335250c89a..fd7def1defb 100644 --- a/tests/introspection/tests.py +++ b/tests/introspection/tests.py @@ -80,15 +80,12 @@ class IntrospectionTests(TransactionTestCase): self.assertEqual( [connection.introspection.get_field_type(r[1], r) for r in desc], [ - connection.features.introspected_field_types['AutoField'], - 'CharField', - 'CharField', - 'CharField', - connection.features.introspected_field_types['BigIntegerField'], - connection.features.introspected_field_types['BinaryField'], - connection.features.introspected_field_types['SmallIntegerField'], - connection.features.introspected_field_types['DurationField'], - ] + connection.features.introspected_field_types[field] for field in ( + 'AutoField', 'CharField', 'CharField', 'CharField', + 'BigIntegerField', 'BinaryField', 'SmallIntegerField', + 'DurationField', + ) + ], ) def test_get_table_description_col_lengths(self): diff --git a/tests/schema/tests.py b/tests/schema/tests.py index 0e479b5f1db..2942b90130b 100644 --- a/tests/schema/tests.py +++ b/tests/schema/tests.py @@ -498,7 +498,7 @@ class SchemaTests(TransactionTestCase): self.assertFalse(any(drop_default_sql in query['sql'] for query in ctx.captured_queries)) # Ensure the field is right afterwards columns = self.column_classes(Author) - self.assertEqual(columns['age'][0], "IntegerField") + self.assertEqual(columns['age'][0], connection.features.introspected_field_types['IntegerField']) self.assertTrue(columns['age'][1][6]) def test_add_field_remove_field(self): @@ -532,7 +532,7 @@ class SchemaTests(TransactionTestCase): editor.add_field(Author, new_field) # Ensure the field is right afterwards columns = self.column_classes(Author) - self.assertEqual(columns['surname'][0], "CharField") + self.assertEqual(columns['surname'][0], connection.features.introspected_field_types['CharField']) self.assertEqual(columns['surname'][1][6], connection.features.interprets_empty_strings_as_nulls) @@ -592,7 +592,7 @@ class SchemaTests(TransactionTestCase): # Ensure the field is there columns = self.column_classes(Author) field_type, field_info = columns['thing'] - self.assertEqual(field_type, 'IntegerField') + self.assertEqual(field_type, connection.features.introspected_field_types['IntegerField']) # Make sure the values were transformed correctly self.assertEqual(Author.objects.extra(where=["thing = 1"]).count(), 2) @@ -640,7 +640,7 @@ class SchemaTests(TransactionTestCase): editor.create_model(Author) # Ensure the field is right to begin with columns = self.column_classes(Author) - self.assertEqual(columns['name'][0], "CharField") + self.assertEqual(columns['name'][0], connection.features.introspected_field_types['CharField']) self.assertEqual(bool(columns['name'][1][6]), bool(connection.features.interprets_empty_strings_as_nulls)) # Alter the name field to a TextField old_field = Author._meta.get_field("name") @@ -1022,7 +1022,7 @@ class SchemaTests(TransactionTestCase): editor.create_model(Book) # Ensure the field is right to begin with columns = self.column_classes(Book) - self.assertEqual(columns['author_id'][0], "IntegerField") + self.assertEqual(columns['author_id'][0], connection.features.introspected_field_types['IntegerField']) self.assertForeignKeyExists(Book, 'author_id', 'schema_author') # Alter the FK old_field = Book._meta.get_field("author") @@ -1032,7 +1032,7 @@ class SchemaTests(TransactionTestCase): editor.alter_field(Book, old_field, new_field, strict=True) # Ensure the field is right afterwards columns = self.column_classes(Book) - self.assertEqual(columns['author_id'][0], "IntegerField") + self.assertEqual(columns['author_id'][0], connection.features.introspected_field_types['IntegerField']) self.assertForeignKeyExists(Book, 'author_id', 'schema_author') @skipUnlessDBFeature('supports_foreign_keys') @@ -1078,7 +1078,7 @@ class SchemaTests(TransactionTestCase): editor.create_model(BookWithO2O) # Ensure the field is right to begin with columns = self.column_classes(BookWithO2O) - self.assertEqual(columns['author_id'][0], "IntegerField") + self.assertEqual(columns['author_id'][0], connection.features.introspected_field_types['IntegerField']) # Ensure the field is unique author = Author.objects.create(name="Joe") BookWithO2O.objects.create(author=author, title="Django 1", pub_date=datetime.datetime.now()) @@ -1094,7 +1094,7 @@ class SchemaTests(TransactionTestCase): editor.alter_field(BookWithO2O, old_field, new_field, strict=True) # Ensure the field is right afterwards columns = self.column_classes(Book) - self.assertEqual(columns['author_id'][0], "IntegerField") + self.assertEqual(columns['author_id'][0], connection.features.introspected_field_types['IntegerField']) # Ensure the field is not unique anymore Book.objects.create(author=author, title="Django 1", pub_date=datetime.datetime.now()) Book.objects.create(author=author, title="Django 2", pub_date=datetime.datetime.now()) @@ -1111,7 +1111,7 @@ class SchemaTests(TransactionTestCase): editor.create_model(Book) # Ensure the field is right to begin with columns = self.column_classes(Book) - self.assertEqual(columns['author_id'][0], "IntegerField") + self.assertEqual(columns['author_id'][0], connection.features.introspected_field_types['IntegerField']) # Ensure the field is not unique author = Author.objects.create(name="Joe") Book.objects.create(author=author, title="Django 1", pub_date=datetime.datetime.now()) @@ -1126,7 +1126,7 @@ class SchemaTests(TransactionTestCase): editor.alter_field(Book, old_field, new_field, strict=True) # Ensure the field is right afterwards columns = self.column_classes(BookWithO2O) - self.assertEqual(columns['author_id'][0], "IntegerField") + self.assertEqual(columns['author_id'][0], connection.features.introspected_field_types['IntegerField']) # Ensure the field is unique now BookWithO2O.objects.create(author=author, title="Django 1", pub_date=datetime.datetime.now()) with self.assertRaises(IntegrityError): @@ -1438,7 +1438,7 @@ class SchemaTests(TransactionTestCase): editor.create_model(Author) # Ensure the field is right to begin with columns = self.column_classes(Author) - self.assertEqual(columns['name'][0], "CharField") + self.assertEqual(columns['name'][0], connection.features.introspected_field_types['CharField']) self.assertNotIn("display_name", columns) # Alter the name field's name old_field = Author._meta.get_field("name") @@ -1448,7 +1448,7 @@ class SchemaTests(TransactionTestCase): editor.alter_field(Author, old_field, new_field, strict=True) # Ensure the field is right afterwards columns = self.column_classes(Author) - self.assertEqual(columns['display_name'][0], "CharField") + self.assertEqual(columns['display_name'][0], connection.features.introspected_field_types['CharField']) self.assertNotIn("name", columns) @isolate_apps('schema') @@ -1516,7 +1516,7 @@ class SchemaTests(TransactionTestCase): editor.create_model(LocalBookWithM2M) # Ensure there is now an m2m table there columns = self.column_classes(LocalBookWithM2M._meta.get_field("tags").remote_field.through) - self.assertEqual(columns['tagm2mtest_id'][0], "IntegerField") + self.assertEqual(columns['tagm2mtest_id'][0], connection.features.introspected_field_types['IntegerField']) def test_m2m_create(self): self._test_m2m_create(ManyToManyField) @@ -1555,8 +1555,8 @@ class SchemaTests(TransactionTestCase): editor.create_model(LocalBookWithM2MThrough) # Ensure there is now an m2m table there columns = self.column_classes(LocalTagThrough) - self.assertEqual(columns['book_id'][0], "IntegerField") - self.assertEqual(columns['tag_id'][0], "IntegerField") + self.assertEqual(columns['book_id'][0], connection.features.introspected_field_types['IntegerField']) + self.assertEqual(columns['tag_id'][0], connection.features.introspected_field_types['IntegerField']) def test_m2m_create_through(self): self._test_m2m_create_through(ManyToManyField) @@ -1595,7 +1595,7 @@ class SchemaTests(TransactionTestCase): editor.add_field(LocalAuthorWithM2M, new_field) # Ensure there is now an m2m table there columns = self.column_classes(new_field.remote_field.through) - self.assertEqual(columns['tagm2mtest_id'][0], "IntegerField") + self.assertEqual(columns['tagm2mtest_id'][0], connection.features.introspected_field_types['IntegerField']) # "Alter" the field. This should not rename the DB table to itself. with connection.schema_editor() as editor: @@ -2268,14 +2268,14 @@ class SchemaTests(TransactionTestCase): editor.create_model(Book) # Ensure the table is there to begin with columns = self.column_classes(Author) - self.assertEqual(columns['name'][0], "CharField") + self.assertEqual(columns['name'][0], connection.features.introspected_field_types['CharField']) # Alter the table with connection.schema_editor(atomic=connection.features.supports_atomic_references_rename) as editor: editor.alter_db_table(Author, "schema_author", "schema_otherauthor") # Ensure the table is there afterwards Author._meta.db_table = "schema_otherauthor" columns = self.column_classes(Author) - self.assertEqual(columns['name'][0], "CharField") + self.assertEqual(columns['name'][0], connection.features.introspected_field_types['CharField']) # Ensure the foreign key reference was updated self.assertForeignKeyExists(Book, "author_id", "schema_otherauthor") # Alter the table again @@ -2284,7 +2284,7 @@ class SchemaTests(TransactionTestCase): # Ensure the table is still there Author._meta.db_table = "schema_author" columns = self.column_classes(Author) - self.assertEqual(columns['name'][0], "CharField") + self.assertEqual(columns['name'][0], connection.features.introspected_field_types['CharField']) def test_add_remove_index(self): """