mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	Edited model and field checks for grammar and consistency.
This commit is contained in:
		| @@ -36,14 +36,14 @@ def check_model_signals(app_configs=None, **kwargs): | |||||||
|                         description = "An instance of the `%s` class" % receiver.__class__.__name__ |                         description = "An instance of the `%s` class" % receiver.__class__.__name__ | ||||||
|                     errors.append( |                     errors.append( | ||||||
|                         Error( |                         Error( | ||||||
|                             "%s was connected to the `%s` signal " |                             "%s was connected to the '%s' signal " | ||||||
|                             "with a lazy reference to the '%s' sender, " |                             "with a lazy reference to the '%s' sender, " | ||||||
|                             "which has not been installed." % ( |                             "which has not been installed." % ( | ||||||
|                                 description, name, '.'.join(reference) |                                 description, name, '.'.join(reference) | ||||||
|                             ), |                             ), | ||||||
|                             obj=receiver.__module__, |                             obj=receiver.__module__, | ||||||
|                             hint=None, |                             hint=None, | ||||||
|                             id='E014' |                             id='signals.E001' | ||||||
|                         ) |                         ) | ||||||
|                     ) |                     ) | ||||||
|     return errors |     return errors | ||||||
|   | |||||||
| @@ -197,10 +197,10 @@ class Field(RegisterLookupMixin): | |||||||
|         if self.name.endswith('_'): |         if self.name.endswith('_'): | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     'Field names must not end with underscores.', |                     'Field names must not end with an underscore.', | ||||||
|                     hint=None, |                     hint=None, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E001', |                     id='fields.E001', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         elif '__' in self.name: |         elif '__' in self.name: | ||||||
| @@ -209,16 +209,16 @@ class Field(RegisterLookupMixin): | |||||||
|                     'Field names must not contain "__".', |                     'Field names must not contain "__".', | ||||||
|                     hint=None, |                     hint=None, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E052', |                     id='fields.E002', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         elif self.name == 'pk': |         elif self.name == 'pk': | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     'Cannot use "pk" as a field name since it is a reserved name.', |                     "'pk' is a reserved word that cannot be used as a field name.", | ||||||
|                     hint=None, |                     hint=None, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E051', |                     id='fields.E003', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         else: |         else: | ||||||
| @@ -230,10 +230,10 @@ class Field(RegisterLookupMixin): | |||||||
|                     not is_iterable(self.choices)): |                     not is_iterable(self.choices)): | ||||||
|                 return [ |                 return [ | ||||||
|                     checks.Error( |                     checks.Error( | ||||||
|                         '"choices" must be an iterable (e.g., a list or tuple).', |                         "'choices' must be an iterable (e.g., a list or tuple).", | ||||||
|                         hint=None, |                         hint=None, | ||||||
|                         obj=self, |                         obj=self, | ||||||
|                         id='E033', |                         id='fields.E004', | ||||||
|                     ) |                     ) | ||||||
|                 ] |                 ] | ||||||
|             elif any(isinstance(choice, six.string_types) or |             elif any(isinstance(choice, six.string_types) or | ||||||
| @@ -241,13 +241,11 @@ class Field(RegisterLookupMixin): | |||||||
|                      for choice in self.choices): |                      for choice in self.choices): | ||||||
|                 return [ |                 return [ | ||||||
|                     checks.Error( |                     checks.Error( | ||||||
|                         ('All "choices" elements must be a tuple of two ' |                         ("'choices' must be an iterable containing " | ||||||
|                          'elements (the first one is the actual value ' |                          "(actual value, human readable name) tuples."), | ||||||
|                          'to be stored and the second element is ' |  | ||||||
|                          'the human-readable name).'), |  | ||||||
|                         hint=None, |                         hint=None, | ||||||
|                         obj=self, |                         obj=self, | ||||||
|                         id='E034', |                         id='fields.E005', | ||||||
|                     ) |                     ) | ||||||
|                 ] |                 ] | ||||||
|             else: |             else: | ||||||
| @@ -259,10 +257,10 @@ class Field(RegisterLookupMixin): | |||||||
|         if self.db_index not in (None, True, False): |         if self.db_index not in (None, True, False): | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     '"db_index" must be either None, True or False.', |                     "'db_index' must be None, True or False.", | ||||||
|                     hint=None, |                     hint=None, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E035', |                     id='fields.E006', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         else: |         else: | ||||||
| @@ -277,10 +275,10 @@ class Field(RegisterLookupMixin): | |||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     'Primary keys must not have null=True.', |                     'Primary keys must not have null=True.', | ||||||
|                     hint=('Set null=False on the field or ' |                     hint=('Set null=False on the field, or ' | ||||||
|                           'remove primary_key=True argument.'), |                           'remove primary_key=True argument.'), | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E036', |                     id='fields.E007', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         else: |         else: | ||||||
| @@ -864,10 +862,10 @@ class AutoField(Field): | |||||||
|         if not self.primary_key: |         if not self.primary_key: | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     'The field must have primary_key=True, because it is an AutoField.', |                     'AutoFields must set primary_key=True.', | ||||||
|                     hint=None, |                     hint=None, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E048', |                     id='fields.E100', | ||||||
|                 ), |                 ), | ||||||
|             ] |             ] | ||||||
|         else: |         else: | ||||||
| @@ -940,10 +938,10 @@ class BooleanField(Field): | |||||||
|         if getattr(self, 'null', False): |         if getattr(self, 'null', False): | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     'BooleanFields do not acceps null values.', |                     'BooleanFields do not accept null values.', | ||||||
|                     hint='Use a NullBooleanField instead.', |                     hint='Use a NullBooleanField instead.', | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E037', |                     id='fields.E110', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         else: |         else: | ||||||
| @@ -1020,19 +1018,19 @@ class CharField(Field): | |||||||
|         except TypeError: |         except TypeError: | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     'The field must have "max_length" attribute.', |                     "CharFields must define a 'max_length' attribute.", | ||||||
|                     hint=None, |                     hint=None, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E038', |                     id='fields.E120', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         except ValueError: |         except ValueError: | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     '"max_length" must be a positive integer.', |                     "'max_length' must be a positive integer.", | ||||||
|                     hint=None, |                     hint=None, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E039', |                     id='fields.E121', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         else: |         else: | ||||||
| @@ -1305,24 +1303,16 @@ class DecimalField(Field): | |||||||
|  |  | ||||||
|     def check(self, **kwargs): |     def check(self, **kwargs): | ||||||
|         errors = super(DecimalField, self).check(**kwargs) |         errors = super(DecimalField, self).check(**kwargs) | ||||||
|  |  | ||||||
|  |         digits_errors = self._check_decimal_places() | ||||||
|  |         digits_errors.extend(self._check_max_digits()) | ||||||
|  |         if not digits_errors: | ||||||
|             errors.extend(self._check_decimal_places_and_max_digits(**kwargs)) |             errors.extend(self._check_decimal_places_and_max_digits(**kwargs)) | ||||||
|  |         else: | ||||||
|  |             errors.extend(digits_errors) | ||||||
|         return errors |         return errors | ||||||
|  |  | ||||||
|     def _check_decimal_places_and_max_digits(self, **kwargs): |     def _check_decimal_places(self): | ||||||
|         errors = self.__check_decimal_places() |  | ||||||
|         errors += self.__check_max_digits() |  | ||||||
|         if not errors and int(self.decimal_places) > int(self.max_digits): |  | ||||||
|             errors.append( |  | ||||||
|                 checks.Error( |  | ||||||
|                     '"max_digits" must be greater or equal to "decimal_places".', |  | ||||||
|                     hint=None, |  | ||||||
|                     obj=self, |  | ||||||
|                     id='E040', |  | ||||||
|                 ) |  | ||||||
|             ) |  | ||||||
|         return errors |  | ||||||
|  |  | ||||||
|     def __check_decimal_places(self): |  | ||||||
|         try: |         try: | ||||||
|             decimal_places = int(self.decimal_places) |             decimal_places = int(self.decimal_places) | ||||||
|             if decimal_places < 0: |             if decimal_places < 0: | ||||||
| @@ -1330,25 +1320,25 @@ class DecimalField(Field): | |||||||
|         except TypeError: |         except TypeError: | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     'The field requires a "decimal_places" attribute.', |                     "DecimalFields must define a 'decimal_places' attribute.", | ||||||
|                     hint=None, |                     hint=None, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E041', |                     id='fields.E130', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         except ValueError: |         except ValueError: | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     '"decimal_places" attribute must be a non-negative integer.', |                     "'decimal_places' must be a non-negative integer.", | ||||||
|                     hint=None, |                     hint=None, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E042', |                     id='fields.E131', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         else: |         else: | ||||||
|             return [] |             return [] | ||||||
|  |  | ||||||
|     def __check_max_digits(self): |     def _check_max_digits(self): | ||||||
|         try: |         try: | ||||||
|             max_digits = int(self.max_digits) |             max_digits = int(self.max_digits) | ||||||
|             if max_digits <= 0: |             if max_digits <= 0: | ||||||
| @@ -1356,24 +1346,36 @@ class DecimalField(Field): | |||||||
|         except TypeError: |         except TypeError: | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     'The field requires a "max_digits" attribute.', |                     "DecimalFields must define a 'max_digits' attribute.", | ||||||
|                     hint=None, |                     hint=None, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E043', |                     id='fields.E132', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         except ValueError: |         except ValueError: | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     '"max_digits" attribute must be a positive integer.', |                     "'max_digits' must be a positive integer.", | ||||||
|                     hint=None, |                     hint=None, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E044', |                     id='fields.E133', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         else: |         else: | ||||||
|             return [] |             return [] | ||||||
|  |  | ||||||
|  |     def _check_decimal_places_and_max_digits(self, **kwargs): | ||||||
|  |         if int(self.decimal_places) > int(self.max_digits): | ||||||
|  |             return [ | ||||||
|  |                 checks.Error( | ||||||
|  |                     "'max_digits' must be greater or equal to 'decimal_places'.", | ||||||
|  |                     hint=None, | ||||||
|  |                     obj=self, | ||||||
|  |                     id='fields.E134', | ||||||
|  |                 ) | ||||||
|  |             ] | ||||||
|  |         return [] | ||||||
|  |  | ||||||
|     def deconstruct(self): |     def deconstruct(self): | ||||||
|         name, path, args, kwargs = super(DecimalField, self).deconstruct() |         name, path, args, kwargs = super(DecimalField, self).deconstruct() | ||||||
|         if self.max_digits: |         if self.max_digits: | ||||||
| @@ -1481,10 +1483,10 @@ class FilePathField(Field): | |||||||
|         if not self.allow_files and not self.allow_folders: |         if not self.allow_files and not self.allow_folders: | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     'The field must have either "allow_files" or "allow_folders" set to True.', |                     "FilePathFields must have either 'allow_files' or 'allow_folders' set to True.", | ||||||
|                     hint=None, |                     hint=None, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E045', |                     id='fields.E140', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         return [] |         return [] | ||||||
| @@ -1659,11 +1661,11 @@ class GenericIPAddressField(Field): | |||||||
|         if not getattr(self, 'null', False) and getattr(self, 'blank', False): |         if not getattr(self, 'null', False) and getattr(self, 'blank', False): | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     ('The field cannot accept blank values if null values ' |                     ('GenericIPAddressFields cannot have blank=True if null=False, ' | ||||||
|                      'are not allowed, as blank values are stored as null.'), |                      'as blank values are stored as nulls.'), | ||||||
|                     hint=None, |                     hint=None, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E046', |                     id='fields.E150', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         return [] |         return [] | ||||||
|   | |||||||
| @@ -246,10 +246,10 @@ class FileField(Field): | |||||||
|         if self._unique_set_explicitly: |         if self._unique_set_explicitly: | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     '"unique" is not a valid argument for %s.' % self.__class__.__name__, |                     "'unique' is not a valid argument for a %s." % self.__class__.__name__, | ||||||
|                     hint=None, |                     hint=None, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E049', |                     id='fields.E200', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         else: |         else: | ||||||
| @@ -259,10 +259,10 @@ class FileField(Field): | |||||||
|         if self._primary_key_set_explicitly: |         if self._primary_key_set_explicitly: | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     '"primary_key" is not a valid argument for %s.' % self.__class__.__name__, |                     "'primary_key' is not a valid argument for a %s." % self.__class__.__name__, | ||||||
|                     hint=None, |                     hint=None, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E050', |                     id='fields.E201', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         else: |         else: | ||||||
| @@ -392,11 +392,11 @@ class ImageField(FileField): | |||||||
|         except ImproperlyConfigured: |         except ImproperlyConfigured: | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     'To use ImageFields, Pillow must be installed.', |                     'Cannot use ImageField because Pillow is not installed.', | ||||||
|                     hint=('Get Pillow at https://pypi.python.org/pypi/Pillow ' |                     hint=('Get Pillow at https://pypi.python.org/pypi/Pillow ' | ||||||
|                           'or run command "pip install pillow".'), |                           'or run command "pip install pillow".'), | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E032', |                     id='fields.E210', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         else: |         else: | ||||||
|   | |||||||
| @@ -108,13 +108,11 @@ class RelatedField(Field): | |||||||
|         if rel_is_missing and (rel_is_string or not self.rel.to._meta.swapped): |         if rel_is_missing and (rel_is_string or not self.rel.to._meta.swapped): | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     ('The field has a relation with model %s, which ' |                     ("Field defines a relation with model '%s', which " | ||||||
|                      'has either not been installed or is abstract.') % model_name, |                      "is either not installed, or is abstract.") % model_name, | ||||||
|                     hint=('Ensure that you did not misspell the model name and ' |                     hint=None, | ||||||
|                           'the model is not abstract. Does your INSTALLED_APPS ' |  | ||||||
|                           'setting contain the app where %s is defined?') % model_name, |  | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E030', |                     id='fields.E300', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         return [] |         return [] | ||||||
| @@ -129,11 +127,11 @@ class RelatedField(Field): | |||||||
|             ) |             ) | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     ('The field defines a relation with the model %s, ' |                     ("Field defines a relation with the model '%s', " | ||||||
|                      'which has been swapped out.') % model, |                      "which has been swapped out.") % model, | ||||||
|                     hint='Update the relation to point at settings.%s' % self.rel.to._meta.swappable, |                     hint="Update the relation to point at 'settings.%s'." % self.rel.to._meta.swappable, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E029', |                     id='fields.E301', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         return [] |         return [] | ||||||
| @@ -190,22 +188,22 @@ class RelatedField(Field): | |||||||
|             if clash_field.name == rel_name: |             if clash_field.name == rel_name: | ||||||
|                 errors.append( |                 errors.append( | ||||||
|                     checks.Error( |                     checks.Error( | ||||||
|                         'Accessor for field %s clashes with field %s.' % (field_name, clash_name), |                         "Reverse accessor for '%s' clashes with field name '%s'." % (field_name, clash_name), | ||||||
|                         hint=('Rename field %s or add/change a related_name ' |                         hint=("Rename field '%s', or add/change a related_name " | ||||||
|                               'argument to the definition for field %s.') % (clash_name, field_name), |                               "argument to the definition for field '%s'.") % (clash_name, field_name), | ||||||
|                         obj=self, |                         obj=self, | ||||||
|                         id='E014', |                         id='fields.E302', | ||||||
|                     ) |                     ) | ||||||
|                 ) |                 ) | ||||||
|  |  | ||||||
|             if clash_field.name == rel_query_name: |             if clash_field.name == rel_query_name: | ||||||
|                 errors.append( |                 errors.append( | ||||||
|                     checks.Error( |                     checks.Error( | ||||||
|                         'Reverse query name for field %s clashes with field %s.' % (field_name, clash_name), |                         "Reverse query name for '%s' clashes with field name '%s'." % (field_name, clash_name), | ||||||
|                         hint=('Rename field %s or add/change a related_name ' |                         hint=("Rename field '%s', or add/change a related_name " | ||||||
|                               'argument to the definition for field %s.') % (clash_name, field_name), |                               "argument to the definition for field '%s'.") % (clash_name, field_name), | ||||||
|                         obj=self, |                         obj=self, | ||||||
|                         id='E015', |                         id='fields.E303', | ||||||
|                     ) |                     ) | ||||||
|                 ) |                 ) | ||||||
|  |  | ||||||
| @@ -223,22 +221,22 @@ class RelatedField(Field): | |||||||
|             if clash_field.get_accessor_name() == rel_name: |             if clash_field.get_accessor_name() == rel_name: | ||||||
|                 errors.append( |                 errors.append( | ||||||
|                     checks.Error( |                     checks.Error( | ||||||
|                         'Clash between accessors for %s and %s.' % (field_name, clash_name), |                         "Reverse accessor for '%s' clashes with reverse accessor for '%s'." % (field_name, clash_name), | ||||||
|                         hint=('Add or change a related_name argument ' |                         hint=("Add or change a related_name argument " | ||||||
|                               'to the definition for %s or %s.') % (field_name, clash_name), |                               "to the definition for '%s' or '%s'.") % (field_name, clash_name), | ||||||
|                         obj=self, |                         obj=self, | ||||||
|                         id='E016', |                         id='fields.E304', | ||||||
|                     ) |                     ) | ||||||
|                 ) |                 ) | ||||||
|  |  | ||||||
|             if clash_field.get_accessor_name() == rel_query_name: |             if clash_field.get_accessor_name() == rel_query_name: | ||||||
|                 errors.append( |                 errors.append( | ||||||
|                     checks.Error( |                     checks.Error( | ||||||
|                         'Clash between reverse query names for %s and %s.' % (field_name, clash_name), |                         "Reverse query name for '%s' clashes with reverse query name for '%s'." % (field_name, clash_name), | ||||||
|                         hint=('Add or change a related_name argument ' |                         hint=("Add or change a related_name argument " | ||||||
|                               'to the definition for %s or %s.') % (field_name, clash_name), |                               "to the definition for '%s' or '%s'.") % (field_name, clash_name), | ||||||
|                         obj=self, |                         obj=self, | ||||||
|                         id='E017', |                         id='fields.E305', | ||||||
|                     ) |                     ) | ||||||
|                 ) |                 ) | ||||||
|  |  | ||||||
| @@ -1317,17 +1315,15 @@ class ForeignObject(RelatedField): | |||||||
|         has_unique_field = any(rel_field.unique |         has_unique_field = any(rel_field.unique | ||||||
|             for rel_field in self.foreign_related_fields) |             for rel_field in self.foreign_related_fields) | ||||||
|         if not has_unique_field and len(self.foreign_related_fields) > 1: |         if not has_unique_field and len(self.foreign_related_fields) > 1: | ||||||
|             field_combination = ','.join(rel_field.name |             field_combination = ', '.join("'%s'" % rel_field.name | ||||||
|                 for rel_field in self.foreign_related_fields) |                 for rel_field in self.foreign_related_fields) | ||||||
|             model_name = self.rel.to.__name__ |             model_name = self.rel.to.__name__ | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     ('No unique=True constraint ' |                     "None of the fields %s on model '%s' have a unique=True constraint." % (field_combination, model_name), | ||||||
|                      'on field combination "%s" under model %s.') % (field_combination, model_name), |                     hint=None, | ||||||
|                     hint=('Set unique=True argument on any of the fields ' |  | ||||||
|                           '"%s" under model %s.') % (field_combination, model_name), |  | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E018', |                     id='fields.E310', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         elif not has_unique_field: |         elif not has_unique_field: | ||||||
| @@ -1335,11 +1331,11 @@ class ForeignObject(RelatedField): | |||||||
|             model_name = self.rel.to.__name__ |             model_name = self.rel.to.__name__ | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     ('%s.%s must have unique=True ' |                     ("'%s.%s' must set unique=True " | ||||||
|                      'because it is referenced by a foreign key.') % (model_name, field_name), |                      "because it is referenced by a foreign key.") % (model_name, field_name), | ||||||
|                     hint=None, |                     hint=None, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E019', |                     id='fields.E311', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         else: |         else: | ||||||
| @@ -1605,19 +1601,19 @@ class ForeignKey(ForeignObject): | |||||||
|         if on_delete == SET_NULL and not self.null: |         if on_delete == SET_NULL and not self.null: | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     'The field specifies on_delete=SET_NULL, but cannot be null.', |                     'Field specifies on_delete=SET_NULL, but cannot be null.', | ||||||
|                     hint='Set null=True argument on the field.', |                     hint='Set null=True argument on the field, or change the on_delete rule.', | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E020', |                     id='fields.E320', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         elif on_delete == SET_DEFAULT and not self.has_default(): |         elif on_delete == SET_DEFAULT and not self.has_default(): | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     'The field specifies on_delete=SET_DEFAULT, but has no default value.', |                     'Field specifies on_delete=SET_DEFAULT, but has no default value.', | ||||||
|                     hint=None, |                     hint='Set a default value, or change the on_delete rule.', | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E021', |                     id='fields.E321', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         else: |         else: | ||||||
| @@ -1864,10 +1860,10 @@ class ManyToManyField(RelatedField): | |||||||
|         if self.unique: |         if self.unique: | ||||||
|             return [ |             return [ | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     'ManyToManyFields must not be unique.', |                     'ManyToManyFields cannot be unique.', | ||||||
|                     hint=None, |                     hint=None, | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E022', |                     id='fields.E330', | ||||||
|                 ) |                 ) | ||||||
|             ] |             ] | ||||||
|         return [] |         return [] | ||||||
| @@ -1879,13 +1875,11 @@ class ManyToManyField(RelatedField): | |||||||
|             # The relationship model is not installed. |             # The relationship model is not installed. | ||||||
|             errors.append( |             errors.append( | ||||||
|                 checks.Error( |                 checks.Error( | ||||||
|                     ('The field specifies a many-to-many relation through model ' |                     ("Field specifies a many-to-many relation through model " | ||||||
|                      '%s, which has not been installed.') % self.rel.through, |                      "'%s', which has not been installed.") % self.rel.through, | ||||||
|                     hint=('Ensure that you did not misspell the model name and ' |                     hint=None, | ||||||
|                           'the model is not abstract. Does your INSTALLED_APPS ' |  | ||||||
|                           'setting contain the app where %s is defined?') % self.rel.through, |  | ||||||
|                     obj=self, |                     obj=self, | ||||||
|                     id='E023', |                     id='fields.E331', | ||||||
|                 ) |                 ) | ||||||
|             ) |             ) | ||||||
|  |  | ||||||
| @@ -1914,7 +1908,7 @@ class ManyToManyField(RelatedField): | |||||||
|                         'Many-to-many fields with intermediate tables must not be symmetrical.', |                         'Many-to-many fields with intermediate tables must not be symmetrical.', | ||||||
|                         hint=None, |                         hint=None, | ||||||
|                         obj=self, |                         obj=self, | ||||||
|                         id='E024', |                         id='fields.E332', | ||||||
|                     ) |                     ) | ||||||
|                 ) |                 ) | ||||||
|  |  | ||||||
| @@ -1926,12 +1920,12 @@ class ManyToManyField(RelatedField): | |||||||
|                 if seen_self > 2: |                 if seen_self > 2: | ||||||
|                     errors.append( |                     errors.append( | ||||||
|                         checks.Error( |                         checks.Error( | ||||||
|                             ('The model is used as an intermediary model by ' |                             ("The model is used as an intermediate model by " | ||||||
|                              '%s, but it has more than two foreign keys ' |                              "'%s', but it has more than two foreign keys " | ||||||
|                              'to %s, which is ambiguous and is not permitted.') % (self, from_model_name), |                              "to '%s', which is ambiguous.") % (self, from_model_name), | ||||||
|                             hint=None, |                             hint=None, | ||||||
|                             obj=self.rel.through, |                             obj=self.rel.through, | ||||||
|                             id='E025', |                             id='fields.E333', | ||||||
|                         ) |                         ) | ||||||
|                     ) |                     ) | ||||||
|  |  | ||||||
| @@ -1945,41 +1939,41 @@ class ManyToManyField(RelatedField): | |||||||
|                 if seen_from > 1: |                 if seen_from > 1: | ||||||
|                     errors.append( |                     errors.append( | ||||||
|                         checks.Error( |                         checks.Error( | ||||||
|                             ('The model is used as an intermediary model by ' |                             ("The model is used as an intermediate model by " | ||||||
|                              '%s, but it has more than one foreign key ' |                              "'%s', but it has more than one foreign key " | ||||||
|                              'to %s, which is ambiguous and is not permitted.') % (self, from_model_name), |                              "from '%s', which is ambiguous.") % (self, from_model_name), | ||||||
|                             hint=('If you want to create a recursive relationship, ' |                             hint=('If you want to create a recursive relationship, ' | ||||||
|                                   'use ForeignKey("self", symmetrical=False, ' |                                   'use ForeignKey("self", symmetrical=False, ' | ||||||
|                                   'through="%s").') % relationship_model_name, |                                   'through="%s").') % relationship_model_name, | ||||||
|                             obj=self, |                             obj=self, | ||||||
|                             id='E026', |                             id='fields.E334', | ||||||
|                         ) |                         ) | ||||||
|                     ) |                     ) | ||||||
|  |  | ||||||
|                 if seen_to > 1: |                 if seen_to > 1: | ||||||
|                     errors.append( |                     errors.append( | ||||||
|                         checks.Error( |                         checks.Error( | ||||||
|                             ('The model is used as an intermediary model by ' |                             ("The model is used as an intermediate model by " | ||||||
|                              '%s, but it has more than one foreign key ' |                              "'%s', but it has more than one foreign key " | ||||||
|                              'to %s, which is ambiguous and is not permitted.') % (self, to_model_name), |                              "to '%s', which is ambiguous.") % (self, to_model_name), | ||||||
|                             hint=('If you want to create a recursive ' |                             hint=('If you want to create a recursive ' | ||||||
|                                   'relationship, use ForeignKey("self", ' |                                   'relationship, use ForeignKey("self", ' | ||||||
|                                   'symmetrical=False, through="%s").') % relationship_model_name, |                                   'symmetrical=False, through="%s").') % relationship_model_name, | ||||||
|                             obj=self, |                             obj=self, | ||||||
|                             id='E027', |                             id='fields.E335', | ||||||
|                         ) |                         ) | ||||||
|                     ) |                     ) | ||||||
|  |  | ||||||
|                 if seen_from == 0 or seen_to == 0: |                 if seen_from == 0 or seen_to == 0: | ||||||
|                     errors.append( |                     errors.append( | ||||||
|                         checks.Error( |                         checks.Error( | ||||||
|                             ('The model is used as an intermediary model by ' |                             ("The model is used as an intermediate model by " | ||||||
|                              '%s, but it misses a foreign key to %s or %s.') % ( |                              "'%s', but it does not have a foreign key to '%s' or '%s'.") % ( | ||||||
|                                 self, from_model_name, to_model_name |                                 self, from_model_name, to_model_name | ||||||
|                             ), |                             ), | ||||||
|                             hint=None, |                             hint=None, | ||||||
|                             obj=self.rel.through, |                             obj=self.rel.through, | ||||||
|                             id='E028', |                             id='fields.E336', | ||||||
|                         ) |                         ) | ||||||
|                     ) |                     ) | ||||||
|         return errors |         return errors | ||||||
|   | |||||||
| @@ -233,13 +233,11 @@ class GenericRelationshipTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.rel.field.check() |         errors = Model.rel.field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             checks.Error( |             checks.Error( | ||||||
|                 ('The field has a relation with model MissingModel, ' |                 ("Field defines a relation with model 'MissingModel', " | ||||||
|                  'which has either not been installed or is abstract.'), |                  "which is either not installed, or is abstract."), | ||||||
|                 hint=('Ensure that you did not misspell the model name and ' |                 hint=None, | ||||||
|                       'the model is not abstract. Does your INSTALLED_APPS ' |  | ||||||
|                       'setting contain the app where MissingModel is defined?'), |  | ||||||
|                 obj=Model.rel.field, |                 obj=Model.rel.field, | ||||||
|                 id='E030', |                 id='fields.E300', | ||||||
|             ) |             ) | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -295,12 +293,12 @@ class GenericRelationshipTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.rel.field.check() |         errors = Model.rel.field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             checks.Error( |             checks.Error( | ||||||
|                 ('The field defines a relation with the model ' |                 ("Field defines a relation with the model " | ||||||
|                  'contenttypes_tests.SwappedModel, ' |                  "'contenttypes_tests.SwappedModel', " | ||||||
|                  'which has been swapped out.'), |                  "which has been swapped out."), | ||||||
|                 hint='Update the relation to point at settings.TEST_SWAPPED_MODEL', |                 hint="Update the relation to point at 'settings.TEST_SWAPPED_MODEL'.", | ||||||
|                 obj=Model.rel.field, |                 obj=Model.rel.field, | ||||||
|                 id='E029', |                 id='fields.E301', | ||||||
|             ) |             ) | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -317,10 +315,10 @@ class GenericRelationshipTests(IsolatedModelsTestCase): | |||||||
|         errors = InvalidBookmark.tags_.field.check() |         errors = InvalidBookmark.tags_.field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             checks.Error( |             checks.Error( | ||||||
|                 'Field names must not end with underscores.', |                 'Field names must not end with an underscore.', | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=InvalidBookmark.tags_.field, |                 obj=InvalidBookmark.tags_.field, | ||||||
|                 id='E001', |                 id='fields.E001', | ||||||
|             ) |             ) | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
|   | |||||||
| @@ -214,16 +214,16 @@ class FieldNamesTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.check() |         errors = Model.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Field names must not end with underscores.', |                 'Field names must not end with an underscore.', | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=Model._meta.get_field('field_'), |                 obj=Model._meta.get_field('field_'), | ||||||
|                 id='E001', |                 id='fields.E001', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 'Field names must not end with underscores.', |                 'Field names must not end with an underscore.', | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=Model._meta.get_field('m2m_'), |                 obj=Model._meta.get_field('m2m_'), | ||||||
|                 id='E001', |                 id='fields.E001', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -238,7 +238,7 @@ class FieldNamesTests(IsolatedModelsTestCase): | |||||||
|                 'Field names must not contain "__".', |                 'Field names must not contain "__".', | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=Model._meta.get_field('some__field'), |                 obj=Model._meta.get_field('some__field'), | ||||||
|                 id='E052', |                 id='fields.E002', | ||||||
|             ) |             ) | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -250,10 +250,10 @@ class FieldNamesTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.check() |         errors = Model.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Cannot use "pk" as a field name since it is a reserved name.', |                 "'pk' is a reserved word that cannot be used as a field name.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=Model._meta.get_field('pk'), |                 obj=Model._meta.get_field('pk'), | ||||||
|                 id='E051', |                 id='fields.E003', | ||||||
|             ) |             ) | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
|   | |||||||
| @@ -35,10 +35,10 @@ class AutoFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'The field must have primary_key=True, because it is an AutoField.', |                 'AutoFields must set primary_key=True.', | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E048', |                 id='fields.E100', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -54,10 +54,10 @@ class BooleanFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'BooleanFields do not acceps null values.', |                 'BooleanFields do not accept null values.', | ||||||
|                 hint='Use a NullBooleanField instead.', |                 hint='Use a NullBooleanField instead.', | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E037', |                 id='fields.E110', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -88,10 +88,10 @@ class CharFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'The field must have "max_length" attribute.', |                 "CharFields must define a 'max_length' attribute.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E038', |                 id='fields.E120', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -104,10 +104,10 @@ class CharFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 '"max_length" must be a positive integer.', |                 "'max_length' must be a positive integer.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E039', |                 id='fields.E121', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -120,10 +120,10 @@ class CharFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 '"max_length" must be a positive integer.', |                 "'max_length' must be a positive integer.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E039', |                 id='fields.E121', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -136,10 +136,10 @@ class CharFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 '"choices" must be an iterable (e.g., a list or tuple).', |                 "'choices' must be an iterable (e.g., a list or tuple).", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E033', |                 id='fields.E004', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -152,12 +152,10 @@ class CharFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 ('All "choices" elements must be a tuple of two elements ' |                 "'choices' must be an iterable containing (actual value, human readable name) tuples.", | ||||||
|                  '(the first one is the actual value to be stored ' |  | ||||||
|                  'and the second element is the human-readable name).'), |  | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E034', |                 id='fields.E005', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -170,10 +168,10 @@ class CharFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 '"db_index" must be either None, True or False.', |                 "'db_index' must be None, True or False.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E035', |                 id='fields.E006', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -210,16 +208,16 @@ class DecimalFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'The field requires a "decimal_places" attribute.', |                 "DecimalFields must define a 'decimal_places' attribute.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E041', |                 id='fields.E130', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 'The field requires a "max_digits" attribute.', |                 "DecimalFields must define a 'max_digits' attribute.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E043', |                 id='fields.E132', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -232,16 +230,16 @@ class DecimalFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 '"decimal_places" attribute must be a non-negative integer.', |                 "'decimal_places' must be a non-negative integer.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E042', |                 id='fields.E131', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 '"max_digits" attribute must be a positive integer.', |                 "'max_digits' must be a positive integer.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E044', |                 id='fields.E133', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -254,16 +252,16 @@ class DecimalFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 '"decimal_places" attribute must be a non-negative integer.', |                 "'decimal_places' must be a non-negative integer.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E042', |                 id='fields.E131', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 '"max_digits" attribute must be a positive integer.', |                 "'max_digits' must be a positive integer.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E044', |                 id='fields.E133', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -276,10 +274,10 @@ class DecimalFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 '"max_digits" must be greater or equal to "decimal_places".', |                 "'max_digits' must be greater or equal to 'decimal_places'.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E040', |                 id='fields.E134', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -313,10 +311,10 @@ class FileFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 '"unique" is not a valid argument for FileField.', |                 "'unique' is not a valid argument for a FileField.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E049', |                 id='fields.E200', | ||||||
|             ) |             ) | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -329,10 +327,10 @@ class FileFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 '"primary_key" is not a valid argument for FileField.', |                 "'primary_key' is not a valid argument for a FileField.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E050', |                 id='fields.E201', | ||||||
|             ) |             ) | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -348,10 +346,10 @@ class FilePathFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'The field must have either "allow_files" or "allow_folders" set to True.', |                 "FilePathFields must have either 'allow_files' or 'allow_folders' set to True.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E045', |                 id='fields.E140', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -367,11 +365,11 @@ class GenericIPAddressFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 ('The field cannot accept blank values if null values ' |                 ('GenericIPAddressFields cannot have blank=True if null=False, ' | ||||||
|                  'are not allowed, as blank values are stored as null.'), |                  'as blank values are stored as nulls.'), | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E046', |                 id='fields.E150', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -394,11 +392,11 @@ class ImageFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [] if pillow_installed else [ |         expected = [] if pillow_installed else [ | ||||||
|             Error( |             Error( | ||||||
|                 'To use ImageFields, Pillow must be installed.', |                 'Cannot use ImageField because Pillow is not installed.', | ||||||
|                 hint=('Get Pillow at https://pypi.python.org/pypi/Pillow ' |                 hint=('Get Pillow at https://pypi.python.org/pypi/Pillow ' | ||||||
|                       'or run command "pip install pillow".'), |                       'or run command "pip install pillow".'), | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E032', |                 id='fields.E210', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
|   | |||||||
| @@ -34,13 +34,11 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 ('The field has a relation with model Rel1, ' |                 ("Field defines a relation with model 'Rel1', " | ||||||
|                  'which has either not been installed or is abstract.'), |                  "which is either not installed, or is abstract."), | ||||||
|                 hint=('Ensure that you did not misspell the model name and ' |                 hint=None, | ||||||
|                       'the model is not abstract. Does your INSTALLED_APPS ' |  | ||||||
|                       'setting contain the app where Rel1 is defined?'), |  | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E030', |                 id='fields.E300', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -53,13 +51,11 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check(from_model=Model) |         errors = field.check(from_model=Model) | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 ('The field has a relation with model Rel2, ' |                 ("Field defines a relation with model 'Rel2', " | ||||||
|                  'which has either not been installed or is abstract.'), |                  "which is either not installed, or is abstract."), | ||||||
|                 hint=('Ensure that you did not misspell the model name and ' |                 hint=None, | ||||||
|                       'the model is not abstract. Does your INSTALLED_APPS ' |  | ||||||
|                       'setting contain the app where Rel2 is defined?'), |  | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E030', |                 id='fields.E300', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -83,15 +79,14 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check(from_model=Group) |         errors = field.check(from_model=Group) | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 ('The model is used as an intermediary model by ' |                 ("The model is used as an intermediate model by " | ||||||
|                  'invalid_models_tests.Group.field, but it has more than one ' |                  "'invalid_models_tests.Group.field', but it has more than one " | ||||||
|                  'foreign key to Person, ' |                  "foreign key to 'Person', which is ambiguous."), | ||||||
|                  'which is ambiguous and is not permitted.'), |  | ||||||
|                 hint=('If you want to create a recursive relationship, use ' |                 hint=('If you want to create a recursive relationship, use ' | ||||||
|                       'ForeignKey("self", symmetrical=False, ' |                       'ForeignKey("self", symmetrical=False, ' | ||||||
|                       'through="AmbiguousRelationship").'), |                       'through="AmbiguousRelationship").'), | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E027', |                 id='fields.E335', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -116,12 +111,12 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check(from_model=Group) |         errors = field.check(from_model=Group) | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 ('The model is used as an intermediary model by ' |                 ("The model is used as an intermediate model by " | ||||||
|                  'invalid_models_tests.Group.members, but it misses ' |                  "'invalid_models_tests.Group.members', but it does not " | ||||||
|                  'a foreign key to Group or Person.'), |                  "have a foreign key to 'Group' or 'Person'."), | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=InvalidRelationship, |                 obj=InvalidRelationship, | ||||||
|                 id='E028', |                 id='fields.E336', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -142,12 +137,12 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check(from_model=Group) |         errors = field.check(from_model=Group) | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 ('The model is used as an intermediary model by ' |                 ("The model is used as an intermediate model by " | ||||||
|                  'invalid_models_tests.Group.members, but it misses ' |                  "'invalid_models_tests.Group.members', but it does not have " | ||||||
|                  'a foreign key to Group or Person.'), |                  "a foreign key to 'Group' or 'Person'."), | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=InvalidRelationship, |                 obj=InvalidRelationship, | ||||||
|                 id='E028', |                 id='fields.E336', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -164,13 +159,11 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check(from_model=Group) |         errors = field.check(from_model=Group) | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 ('The field specifies a many-to-many relation through model ' |                 ("Field specifies a many-to-many relation through model " | ||||||
|                  'MissingM2MModel, which has not been installed.'), |                  "'MissingM2MModel', which has not been installed."), | ||||||
|                 hint=('Ensure that you did not misspell the model name and ' |                 hint=None, | ||||||
|                       'the model is not abstract. Does your INSTALLED_APPS ' |  | ||||||
|                       'setting contain the app where MissingM2MModel is defined?'), |  | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E023', |                 id='fields.E331', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -191,7 +184,7 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|                 'Many-to-many fields with intermediate tables must not be symmetrical.', |                 'Many-to-many fields with intermediate tables must not be symmetrical.', | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E024', |                 id='fields.E332', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -210,13 +203,12 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check(from_model=Person) |         errors = field.check(from_model=Person) | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 ('The model is used as an intermediary model by ' |                 ("The model is used as an intermediate model by " | ||||||
|                  'invalid_models_tests.Person.friends, but it has more than two ' |                  "'invalid_models_tests.Person.friends', but it has more than two " | ||||||
|                  'foreign keys to Person, which is ambiguous and ' |                  "foreign keys to 'Person', which is ambiguous."), | ||||||
|                  'is not permitted.'), |  | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=InvalidRelationship, |                 obj=InvalidRelationship, | ||||||
|                 id='E025', |                 id='fields.E333', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -238,7 +230,7 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|                 'Many-to-many fields with intermediate tables must not be symmetrical.', |                 'Many-to-many fields with intermediate tables must not be symmetrical.', | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E024', |                 id='fields.E332', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -255,13 +247,11 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 ('The field has a relation with model AbstractModel, ' |                 ("Field defines a relation with model 'AbstractModel', " | ||||||
|                  'which has either not been installed or is abstract.'), |                  "which is either not installed, or is abstract."), | ||||||
|                 hint=('Ensure that you did not misspell the model name and ' |                 hint=None, | ||||||
|                       'the model is not abstract. Does your INSTALLED_APPS ' |  | ||||||
|                       'setting contain the app where AbstractModel is defined?'), |  | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E030', |                 id='fields.E300', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -278,13 +268,11 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check(from_model=Model) |         errors = field.check(from_model=Model) | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 ('The field has a relation with model AbstractModel, ' |                 ("Field defines a relation with model 'AbstractModel', " | ||||||
|                  'which has either not been installed or is abstract.'), |                  "which is either not installed, or is abstract."), | ||||||
|                 hint=('Ensure that you did not misspell the model name and ' |                 hint=None, | ||||||
|                       'the model is not abstract. Does your INSTALLED_APPS ' |  | ||||||
|                       'setting contain the app where AbstractModel is defined?'), |  | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E030', |                 id='fields.E300', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -300,10 +288,10 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check(from_model=Group) |         errors = field.check(from_model=Group) | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'ManyToManyFields must not be unique.', |                 'ManyToManyFields cannot be unique.', | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E022', |                 id='fields.E330', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -319,10 +307,10 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Target.bad must have unique=True because it is referenced by a foreign key.', |                 "'Target.bad' must set unique=True because it is referenced by a foreign key.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E019', |                 id='fields.E311', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -338,10 +326,10 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Target.bad must have unique=True because it is referenced by a foreign key.', |                 "'Target.bad' must set unique=True because it is referenced by a foreign key.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E019', |                 id='fields.E311', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -364,12 +352,11 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 ('No unique=True constraint on field combination ' |                 ("None of the fields 'country_id', 'city_id' on model 'Person' " | ||||||
|                  '"country_id,city_id" under model Person.'), |                  "have a unique=True constraint."), | ||||||
|                 hint=('Set unique=True argument on any of the fields ' |                 hint=None, | ||||||
|                       '"country_id,city_id" under model Person.'), |  | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E018', |                 id='fields.E310', | ||||||
|             ) |             ) | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -386,10 +373,10 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'The field specifies on_delete=SET_NULL, but cannot be null.', |                 'Field specifies on_delete=SET_NULL, but cannot be null.', | ||||||
|                 hint='Set null=True argument on the field.', |                 hint='Set null=True argument on the field, or change the on_delete rule.', | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E020', |                 id='fields.E320', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -406,10 +393,10 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|         errors = field.check() |         errors = field.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'The field specifies on_delete=SET_DEFAULT, but has no default value.', |                 'Field specifies on_delete=SET_DEFAULT, but has no default value.', | ||||||
|                 hint=None, |                 hint='Set a default value, or change the on_delete rule.', | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E021', |                 id='fields.E321', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -424,9 +411,9 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Primary keys must not have null=True.', |                 'Primary keys must not have null=True.', | ||||||
|                 hint='Set null=False on the field or remove primary_key=True argument.', |                 hint='Set null=False on the field, or remove primary_key=True argument.', | ||||||
|                 obj=field, |                 obj=field, | ||||||
|                 id='E036', |                 id='fields.E007', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -489,10 +476,10 @@ class RelativeFieldTests(IsolatedModelsTestCase): | |||||||
|         ] |         ] | ||||||
|  |  | ||||||
|         expected_error = Error( |         expected_error = Error( | ||||||
|             ('The field defines a relation with the model ' |             ("Field defines a relation with the model " | ||||||
|              'invalid_models_tests.SwappedModel, which has been swapped out.'), |              "'invalid_models_tests.SwappedModel', which has been swapped out."), | ||||||
|             hint='Update the relation to point at settings.TEST_SWAPPED_MODEL', |             hint="Update the relation to point at 'settings.TEST_SWAPPED_MODEL'.", | ||||||
|             id='E029', |             id='fields.E301', | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         for field in fields: |         for field in fields: | ||||||
| @@ -546,12 +533,12 @@ class AccessorClashTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.check() |         errors = Model.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Accessor for field Model.rel clashes with field Target.model_set.', |                 "Reverse accessor for 'Model.rel' clashes with field name 'Target.model_set'.", | ||||||
|                 hint=('Rename field Target.model_set or add/change ' |                 hint=("Rename field 'Target.model_set', or add/change " | ||||||
|                       'a related_name argument to the definition ' |                       "a related_name argument to the definition " | ||||||
|                       'for field Model.rel.'), |                       "for field 'Model.rel'."), | ||||||
|                 obj=Model._meta.get_field('rel'), |                 obj=Model._meta.get_field('rel'), | ||||||
|                 id='E014', |                 id='fields.E302', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -567,18 +554,18 @@ class AccessorClashTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.check() |         errors = Model.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Clash between accessors for Model.foreign and Model.m2m.', |                 "Reverse accessor for 'Model.foreign' clashes with reverse accessor for 'Model.m2m'.", | ||||||
|                 hint=('Add or change a related_name argument to the definition ' |                 hint=("Add or change a related_name argument to the definition " | ||||||
|                       'for Model.foreign or Model.m2m.'), |                       "for 'Model.foreign' or 'Model.m2m'."), | ||||||
|                 obj=Model._meta.get_field('foreign'), |                 obj=Model._meta.get_field('foreign'), | ||||||
|                 id='E016', |                 id='fields.E304', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 'Clash between accessors for Model.m2m and Model.foreign.', |                 "Reverse accessor for 'Model.m2m' clashes with reverse accessor for 'Model.foreign'.", | ||||||
|                 hint=('Add or change a related_name argument to the definition ' |                 hint=("Add or change a related_name argument to the definition " | ||||||
|                       'for Model.m2m or Model.foreign.'), |                       "for 'Model.m2m' or 'Model.foreign'."), | ||||||
|                 obj=Model._meta.get_field('m2m'), |                 obj=Model._meta.get_field('m2m'), | ||||||
|                 id='E016', |                 id='fields.E304', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -602,12 +589,12 @@ class AccessorClashTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.check() |         errors = Model.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Accessor for field Model.children clashes with field Child.m2m_clash.', |                 "Reverse accessor for 'Model.children' clashes with field name 'Child.m2m_clash'.", | ||||||
|                 hint=('Rename field Child.m2m_clash or add/change ' |                 hint=("Rename field 'Child.m2m_clash', or add/change " | ||||||
|                       'a related_name argument to the definition ' |                       "a related_name argument to the definition " | ||||||
|                       'for field Model.children.'), |                       "for field 'Model.children'."), | ||||||
|                 obj=Model._meta.get_field('children'), |                 obj=Model._meta.get_field('children'), | ||||||
|                 id='E014', |                 id='fields.E302', | ||||||
|             ) |             ) | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -658,12 +645,12 @@ class ReverseQueryNameClashTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.check() |         errors = Model.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Reverse query name for field Model.rel clashes with field Target.model.', |                 "Reverse query name for 'Model.rel' clashes with field name 'Target.model'.", | ||||||
|                 hint=('Rename field Target.model or add/change ' |                 hint=("Rename field 'Target.model', or add/change " | ||||||
|                       'a related_name argument to the definition ' |                       "a related_name argument to the definition " | ||||||
|                       'for field Model.rel.'), |                       "for field 'Model.rel'."), | ||||||
|                 obj=Model._meta.get_field('rel'), |                 obj=Model._meta.get_field('rel'), | ||||||
|                 id='E015', |                 id='fields.E303', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -714,20 +701,20 @@ class ExplicitRelatedNameClashTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.check() |         errors = Model.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Accessor for field Model.rel clashes with field Target.clash.', |                 "Reverse accessor for 'Model.rel' clashes with field name 'Target.clash'.", | ||||||
|                 hint=('Rename field Target.clash or add/change ' |                 hint=("Rename field 'Target.clash', or add/change " | ||||||
|                       'a related_name argument to the definition ' |                       "a related_name argument to the definition " | ||||||
|                       'for field Model.rel.'), |                       "for field 'Model.rel'."), | ||||||
|                 obj=Model._meta.get_field('rel'), |                 obj=Model._meta.get_field('rel'), | ||||||
|                 id='E014', |                 id='fields.E302', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 'Reverse query name for field Model.rel clashes with field Target.clash.', |                 "Reverse query name for 'Model.rel' clashes with field name 'Target.clash'.", | ||||||
|                 hint=('Rename field Target.clash or add/change ' |                 hint=("Rename field 'Target.clash', or add/change " | ||||||
|                       'a related_name argument to the definition ' |                       "a related_name argument to the definition " | ||||||
|                       'for field Model.rel.'), |                       "for field 'Model.rel'."), | ||||||
|                 obj=Model._meta.get_field('rel'), |                 obj=Model._meta.get_field('rel'), | ||||||
|                 id='E015', |                 id='fields.E303', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -784,11 +771,11 @@ class ExplicitRelatedQueryNameClashTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.check() |         errors = Model.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Reverse query name for field Model.rel clashes with field Target.clash.', |                 "Reverse query name for 'Model.rel' clashes with field name 'Target.clash'.", | ||||||
|                 hint=('Rename field Target.clash or add/change a related_name ' |                 hint=("Rename field 'Target.clash', or add/change a related_name " | ||||||
|                       'argument to the definition for field Model.rel.'), |                       "argument to the definition for field 'Model.rel'."), | ||||||
|                 obj=Model._meta.get_field('rel'), |                 obj=Model._meta.get_field('rel'), | ||||||
|                 id='E015', |                 id='fields.E303', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -804,18 +791,18 @@ class SelfReferentialM2MClashTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.check() |         errors = Model.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Clash between accessors for Model.first_m2m and Model.second_m2m.', |                 "Reverse accessor for 'Model.first_m2m' clashes with reverse accessor for 'Model.second_m2m'.", | ||||||
|                 hint=('Add or change a related_name argument to the definition ' |                 hint=("Add or change a related_name argument to the definition " | ||||||
|                       'for Model.first_m2m or Model.second_m2m.'), |                       "for 'Model.first_m2m' or 'Model.second_m2m'."), | ||||||
|                 obj=Model._meta.get_field('first_m2m'), |                 obj=Model._meta.get_field('first_m2m'), | ||||||
|                 id='E016', |                 id='fields.E304', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 'Clash between accessors for Model.second_m2m and Model.first_m2m.', |                 "Reverse accessor for 'Model.second_m2m' clashes with reverse accessor for 'Model.first_m2m'.", | ||||||
|                 hint=('Add or change a related_name argument to the definition ' |                 hint=("Add or change a related_name argument to the definition " | ||||||
|                       'for Model.second_m2m or Model.first_m2m.'), |                       "for 'Model.second_m2m' or 'Model.first_m2m'."), | ||||||
|                 obj=Model._meta.get_field('second_m2m'), |                 obj=Model._meta.get_field('second_m2m'), | ||||||
|                 id='E016', |                 id='fields.E304', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -827,12 +814,12 @@ class SelfReferentialM2MClashTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.check() |         errors = Model.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Accessor for field Model.model_set clashes with field Model.model_set.', |                 "Reverse accessor for 'Model.model_set' clashes with field name 'Model.model_set'.", | ||||||
|                 hint=('Rename field Model.model_set or add/change ' |                 hint=("Rename field 'Model.model_set', or add/change " | ||||||
|                      'a related_name argument to the definition ' |                       "a related_name argument to the definition " | ||||||
|                      'for field Model.model_set.'), |                       "for field 'Model.model_set'."), | ||||||
|                 obj=Model._meta.get_field('model_set'), |                 obj=Model._meta.get_field('model_set'), | ||||||
|                 id='E014', |                 id='fields.E302', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -844,11 +831,11 @@ class SelfReferentialM2MClashTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.check() |         errors = Model.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Reverse query name for field Model.model clashes with field Model.model.', |                 "Reverse query name for 'Model.model' clashes with field name 'Model.model'.", | ||||||
|                 hint=('Rename field Model.model or add/change a related_name ' |                 hint=("Rename field 'Model.model', or add/change a related_name " | ||||||
|                       'argument to the definition for field Model.model.'), |                       "argument to the definition for field 'Model.model'."), | ||||||
|                 obj=Model._meta.get_field('model'), |                 obj=Model._meta.get_field('model'), | ||||||
|                 id='E015', |                 id='fields.E303', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -862,18 +849,18 @@ class SelfReferentialM2MClashTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.check() |         errors = Model.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Accessor for field Model.m2m clashes with field Model.clash.', |                 "Reverse accessor for 'Model.m2m' clashes with field name 'Model.clash'.", | ||||||
|                 hint=('Rename field Model.clash or add/change a related_name ' |                 hint=("Rename field 'Model.clash', or add/change a related_name " | ||||||
|                       'argument to the definition for field Model.m2m.'), |                       "argument to the definition for field 'Model.m2m'."), | ||||||
|                 obj=Model._meta.get_field('m2m'), |                 obj=Model._meta.get_field('m2m'), | ||||||
|                 id='E014', |                 id='fields.E302', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 'Reverse query name for field Model.m2m clashes with field Model.clash.', |                 "Reverse query name for 'Model.m2m' clashes with field name 'Model.clash'.", | ||||||
|                 hint=('Rename field Model.clash or add/change a related_name ' |                 hint=("Rename field 'Model.clash', or add/change a related_name " | ||||||
|                       'argument to the definition for field Model.m2m.'), |                       "argument to the definition for field 'Model.m2m'."), | ||||||
|                 obj=Model._meta.get_field('m2m'), |                 obj=Model._meta.get_field('m2m'), | ||||||
|                 id='E015', |                 id='fields.E303', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -898,12 +885,12 @@ class SelfReferentialFKClashTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.check() |         errors = Model.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Accessor for field Model.model_set clashes with field Model.model_set.', |                 "Reverse accessor for 'Model.model_set' clashes with field name 'Model.model_set'.", | ||||||
|                 hint=('Rename field Model.model_set or add/change ' |                 hint=("Rename field 'Model.model_set', or add/change " | ||||||
|                       'a related_name argument to the definition ' |                       "a related_name argument to the definition " | ||||||
|                       'for field Model.model_set.'), |                       "for field 'Model.model_set'."), | ||||||
|                 obj=Model._meta.get_field('model_set'), |                 obj=Model._meta.get_field('model_set'), | ||||||
|                 id='E014', |                 id='fields.E302', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -915,12 +902,12 @@ class SelfReferentialFKClashTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.check() |         errors = Model.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Reverse query name for field Model.model clashes with field Model.model.', |                 "Reverse query name for 'Model.model' clashes with field name 'Model.model'.", | ||||||
|                 hint=('Rename field Model.model or add/change ' |                 hint=("Rename field 'Model.model', or add/change " | ||||||
|                       'a related_name argument to the definition ' |                       "a related_name argument to the definition " | ||||||
|                       'for field Model.model.'), |                       "for field 'Model.model'."), | ||||||
|                 obj=Model._meta.get_field('model'), |                 obj=Model._meta.get_field('model'), | ||||||
|                 id='E015', |                 id='fields.E303', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -933,20 +920,20 @@ class SelfReferentialFKClashTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.check() |         errors = Model.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Accessor for field Model.foreign clashes with field Model.clash.', |                 "Reverse accessor for 'Model.foreign' clashes with field name 'Model.clash'.", | ||||||
|                 hint=('Rename field Model.clash or add/change ' |                 hint=("Rename field 'Model.clash', or add/change " | ||||||
|                       'a related_name argument to the definition ' |                       "a related_name argument to the definition " | ||||||
|                       'for field Model.foreign.'), |                       "for field 'Model.foreign'."), | ||||||
|                 obj=Model._meta.get_field('foreign'), |                 obj=Model._meta.get_field('foreign'), | ||||||
|                 id='E014', |                 id='fields.E302', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 'Reverse query name for field Model.foreign clashes with field Model.clash.', |                 "Reverse query name for 'Model.foreign' clashes with field name 'Model.clash'.", | ||||||
|                 hint=('Rename field Model.clash or add/change ' |                 hint=("Rename field 'Model.clash', or add/change " | ||||||
|                       'a related_name argument to the definition ' |                       "a related_name argument to the definition " | ||||||
|                       'for field Model.foreign.'), |                       "for field 'Model.foreign'."), | ||||||
|                 obj=Model._meta.get_field('foreign'), |                 obj=Model._meta.get_field('foreign'), | ||||||
|                 id='E015', |                 id='fields.E303', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
| @@ -976,91 +963,91 @@ class ComplexClashTests(IsolatedModelsTestCase): | |||||||
|         errors = Model.check() |         errors = Model.check() | ||||||
|         expected = [ |         expected = [ | ||||||
|             Error( |             Error( | ||||||
|                 'Accessor for field Model.foreign_1 clashes with field Target.id.', |                 "Reverse accessor for 'Model.foreign_1' clashes with field name 'Target.id'.", | ||||||
|                 hint=('Rename field Target.id or add/change a related_name ' |                 hint=("Rename field 'Target.id', or add/change a related_name " | ||||||
|                       'argument to the definition for field Model.foreign_1.'), |                       "argument to the definition for field 'Model.foreign_1'."), | ||||||
|                 obj=Model._meta.get_field('foreign_1'), |                 obj=Model._meta.get_field('foreign_1'), | ||||||
|                 id='E014', |                 id='fields.E302', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 'Reverse query name for field Model.foreign_1 clashes with field Target.id.', |                 "Reverse query name for 'Model.foreign_1' clashes with field name 'Target.id'.", | ||||||
|                 hint=('Rename field Target.id or add/change a related_name ' |                 hint=("Rename field 'Target.id', or add/change a related_name " | ||||||
|                       'argument to the definition for field Model.foreign_1.'), |                       "argument to the definition for field 'Model.foreign_1'."), | ||||||
|                 obj=Model._meta.get_field('foreign_1'), |                 obj=Model._meta.get_field('foreign_1'), | ||||||
|                 id='E015', |                 id='fields.E303', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 'Clash between accessors for Model.foreign_1 and Model.m2m_1.', |                 "Reverse accessor for 'Model.foreign_1' clashes with reverse accessor for 'Model.m2m_1'.", | ||||||
|                 hint=('Add or change a related_name argument to ' |                 hint=("Add or change a related_name argument to " | ||||||
|                       'the definition for Model.foreign_1 or Model.m2m_1.'), |                       "the definition for 'Model.foreign_1' or 'Model.m2m_1'."), | ||||||
|                 obj=Model._meta.get_field('foreign_1'), |                 obj=Model._meta.get_field('foreign_1'), | ||||||
|                 id='E016', |                 id='fields.E304', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 'Clash between reverse query names for Model.foreign_1 and Model.m2m_1.', |                 "Reverse query name for 'Model.foreign_1' clashes with reverse query name for 'Model.m2m_1'.", | ||||||
|                 hint=('Add or change a related_name argument to ' |                 hint=("Add or change a related_name argument to " | ||||||
|                       'the definition for Model.foreign_1 or Model.m2m_1.'), |                       "the definition for 'Model.foreign_1' or 'Model.m2m_1'."), | ||||||
|                 obj=Model._meta.get_field('foreign_1'), |                 obj=Model._meta.get_field('foreign_1'), | ||||||
|                 id='E017', |                 id='fields.E305', | ||||||
|             ), |             ), | ||||||
|  |  | ||||||
|             Error( |             Error( | ||||||
|                 'Clash between accessors for Model.foreign_2 and Model.m2m_2.', |                 "Reverse accessor for 'Model.foreign_2' clashes with reverse accessor for 'Model.m2m_2'.", | ||||||
|                 hint=('Add or change a related_name argument ' |                 hint=("Add or change a related_name argument " | ||||||
|                       'to the definition for Model.foreign_2 or Model.m2m_2.'), |                       "to the definition for 'Model.foreign_2' or 'Model.m2m_2'."), | ||||||
|                 obj=Model._meta.get_field('foreign_2'), |                 obj=Model._meta.get_field('foreign_2'), | ||||||
|                 id='E016', |                 id='fields.E304', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 'Clash between reverse query names for Model.foreign_2 and Model.m2m_2.', |                 "Reverse query name for 'Model.foreign_2' clashes with reverse query name for 'Model.m2m_2'.", | ||||||
|                 hint=('Add or change a related_name argument to ' |                 hint=("Add or change a related_name argument to " | ||||||
|                       'the definition for Model.foreign_2 or Model.m2m_2.'), |                       "the definition for 'Model.foreign_2' or 'Model.m2m_2'."), | ||||||
|                 obj=Model._meta.get_field('foreign_2'), |                 obj=Model._meta.get_field('foreign_2'), | ||||||
|                 id='E017', |                 id='fields.E305', | ||||||
|             ), |             ), | ||||||
|  |  | ||||||
|             Error( |             Error( | ||||||
|                 'Accessor for field Model.m2m_1 clashes with field Target.id.', |                 "Reverse accessor for 'Model.m2m_1' clashes with field name 'Target.id'.", | ||||||
|                 hint=('Rename field Target.id or add/change a related_name ' |                 hint=("Rename field 'Target.id', or add/change a related_name " | ||||||
|                       'argument to the definition for field Model.m2m_1.'), |                       "argument to the definition for field 'Model.m2m_1'."), | ||||||
|                 obj=Model._meta.get_field('m2m_1'), |                 obj=Model._meta.get_field('m2m_1'), | ||||||
|                 id='E014', |                 id='fields.E302', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 'Reverse query name for field Model.m2m_1 clashes with field Target.id.', |                 "Reverse query name for 'Model.m2m_1' clashes with field name 'Target.id'.", | ||||||
|                 hint=('Rename field Target.id or add/change a related_name ' |                 hint=("Rename field 'Target.id', or add/change a related_name " | ||||||
|                       'argument to the definition for field Model.m2m_1.'), |                       "argument to the definition for field 'Model.m2m_1'."), | ||||||
|                 obj=Model._meta.get_field('m2m_1'), |                 obj=Model._meta.get_field('m2m_1'), | ||||||
|                 id='E015', |                 id='fields.E303', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 'Clash between accessors for Model.m2m_1 and Model.foreign_1.', |                 "Reverse accessor for 'Model.m2m_1' clashes with reverse accessor for 'Model.foreign_1'.", | ||||||
|                 hint=('Add or change a related_name argument to the definition ' |                 hint=("Add or change a related_name argument to the definition " | ||||||
|                       'for Model.m2m_1 or Model.foreign_1.'), |                       "for 'Model.m2m_1' or 'Model.foreign_1'."), | ||||||
|                 obj=Model._meta.get_field('m2m_1'), |                 obj=Model._meta.get_field('m2m_1'), | ||||||
|                 id='E016', |                 id='fields.E304', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 'Clash between reverse query names for Model.m2m_1 and Model.foreign_1.', |                 "Reverse query name for 'Model.m2m_1' clashes with reverse query name for 'Model.foreign_1'.", | ||||||
|                 hint=('Add or change a related_name argument to ' |                 hint=("Add or change a related_name argument to " | ||||||
|                       'the definition for Model.m2m_1 or Model.foreign_1.'), |                       "the definition for 'Model.m2m_1' or 'Model.foreign_1'."), | ||||||
|                 obj=Model._meta.get_field('m2m_1'), |                 obj=Model._meta.get_field('m2m_1'), | ||||||
|                 id='E017', |                 id='fields.E305', | ||||||
|             ), |             ), | ||||||
|  |  | ||||||
|             Error( |             Error( | ||||||
|                 'Clash between accessors for Model.m2m_2 and Model.foreign_2.', |                 "Reverse accessor for 'Model.m2m_2' clashes with reverse accessor for 'Model.foreign_2'.", | ||||||
|                 hint=('Add or change a related_name argument to the definition ' |                 hint=("Add or change a related_name argument to the definition " | ||||||
|                       'for Model.m2m_2 or Model.foreign_2.'), |                       "for 'Model.m2m_2' or 'Model.foreign_2'."), | ||||||
|                 obj=Model._meta.get_field('m2m_2'), |                 obj=Model._meta.get_field('m2m_2'), | ||||||
|                 id='E016', |                 id='fields.E304', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 'Clash between reverse query names for Model.m2m_2 and Model.foreign_2.', |                 "Reverse query name for 'Model.m2m_2' clashes with reverse query name for 'Model.foreign_2'.", | ||||||
|                 hint=('Add or change a related_name argument to the definition ' |                 hint=("Add or change a related_name argument to the definition " | ||||||
|                       'for Model.m2m_2 or Model.foreign_2.'), |                       "for 'Model.m2m_2' or 'Model.foreign_2'."), | ||||||
|                 obj=Model._meta.get_field('m2m_2'), |                 obj=Model._meta.get_field('m2m_2'), | ||||||
|                 id='E017', |                 id='fields.E305', | ||||||
|             ), |             ), | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ class ModelValidationTest(TestCase): | |||||||
|                 "sender, which has not been installed.", |                 "sender, which has not been installed.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj='model_validation.tests', |                 obj='model_validation.tests', | ||||||
|                 id='E014', |                 id='signals.E001', | ||||||
|             ), |             ), | ||||||
|             Error( |             Error( | ||||||
|                 "An instance of the `OnPostInit` class was connected to " |                 "An instance of the `OnPostInit` class was connected to " | ||||||
| @@ -45,7 +45,7 @@ class ModelValidationTest(TestCase): | |||||||
|                 "'missing-app.Model' sender, which has not been installed.", |                 "'missing-app.Model' sender, which has not been installed.", | ||||||
|                 hint=None, |                 hint=None, | ||||||
|                 obj='model_validation.tests', |                 obj='model_validation.tests', | ||||||
|                 id='E014', |                 id='signals.E001', | ||||||
|             ) |             ) | ||||||
|         ] |         ] | ||||||
|         self.assertEqual(errors, expected) |         self.assertEqual(errors, expected) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user