def check_field_type(self, field, field_type): """ MySQL has the following field length restriction: No character (varchar) fields can have a length exceeding 255 characters if they have a unique index on them. MySQL doesn't support a database index on some data types. """ errors = [] if (field_type.startswith('varchar') and field.unique and (field.max_length is None or int(field.max_length) > 255)): errors.append( checks.Error( 'MySQL does not allow unique CharFields to have a max_length > 255.', obj=field, id='mysql.E001', )) if field.db_index and field_type.lower( ) in self.connection._limited_data_types: errors.append( checks.Warning( 'MySQL does not support a database index on %s columns.' % field_type, hint=("An index won't be created. Silence this warning if " "you don't care about it."), obj=field, id='fields.W162', )) return errors
def test_default_details(self): class MyField(models.Field): system_check_deprecated_details = {} class Model(models.Model): name = MyField() model = Model() self.assertEqual(model.check(), [ checks.Warning( msg='MyField has been deprecated.', obj=Model._meta.get_field('name'), id='fields.WXXX', ) ])
def _check_default(self): if self.has_default() and self.default is not None and not callable( self.default): return [ checks.Warning( "%s default should be a callable instead of an instance so " "that it's not shared between all field instances." % (self.__class__.__name__, ), hint=('Use a callable instead, e.g., use `%s` instead of ' '`%s`.' % self._default_hint), obj=self, id='postgres.E003', ) ] else: return []
def test_invalid_default(self): class MyModel(PostgreSQLModel): field = HStoreField(default={}) model = MyModel() self.assertEqual(model.check(), [ checks.Warning( msg=( "HStoreField default should be a callable instead of an " "instance so that it's not shared between all field " "instances." ), hint='Use a callable instead, e.g., use `dict` instead of `{}`.', obj=MyModel._meta.get_field('field'), id='postgres.E003', ) ])
def check_field_type(self, field, field_type): """Oracle doesn't support a database index on some data types.""" errors = [] if field.db_index and field_type.lower() in self.connection._limited_data_types: errors.append( checks.Warning( 'Oracle does not support a database index on %s columns.' % field_type, hint=( "An index won't be created. Silence this warning if " "you don't care about it." ), obj=field, id='fields.W162', ) ) return errors
def test_warning_when_unique_true_on_fk(self): class Foo(models.Model): pass class FKUniqueTrue(models.Model): fk_field = models.ForeignKey(Foo, models.CASCADE, unique=True) model = FKUniqueTrue() expected_warnings = [ checks.Warning( 'Setting unique=True on a ForeignKey has the same effect as using a OneToOneField.', hint= 'ForeignKey(unique=True) is usually better served by a OneToOneField.', obj=FKUniqueTrue.fk_field.field, id='fields.W342', ) ] warnings = model.check() self.assertEqual(warnings, expected_warnings)
def test_user_specified_details(self): class MyField(models.Field): system_check_deprecated_details = { 'msg': 'This field is deprecated and will be removed soon.', 'hint': 'Use something else.', 'id': 'fields.W999', } class Model(models.Model): name = MyField() model = Model() self.assertEqual(model.check(), [ checks.Warning( msg='This field is deprecated and will be removed soon.', hint='Use something else.', obj=Model._meta.get_field('name'), id='fields.W999', ) ])
def _check_sql_mode(self, **kwargs): with self.connection.cursor() as cursor: cursor.execute("SELECT @@sql_mode") sql_mode = cursor.fetchone() modes = set(sql_mode[0].split(',') if sql_mode else ()) if not (modes & {'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES'}): return [ checks.Warning( "MySQL Strict Mode is not set for database connection '%s'" % self.connection.alias, hint= "MySQL's Strict Mode fixes many data integrity problems in MySQL, " "such as data truncation upon insertion, by escalating warnings into " "errors. It is strongly recommended you activate it. See: " "https://docs.djangoproject.com/en/%s/ref/databases/#mysql-sql-mode" % (get_docs_version(), ), id='mysql.W002', ) ] return []
def deployment_system_check(**kwargs): deployment_system_check.kwargs = kwargs return [checks.Warning('Deployment Check')]
def tagged_system_check(**kwargs): tagged_system_check.kwargs = kwargs return [checks.Warning('System Check')]