plain.models 0.44.0__py3-none-any.whl → 0.46.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,11 +9,12 @@ import warnings
9
9
  from base64 import b64decode, b64encode
10
10
  from functools import cached_property, partialmethod, total_ordering
11
11
 
12
- from plain import exceptions, preflight, validators
12
+ from plain import exceptions, validators
13
13
  from plain.models.constants import LOOKUP_SEP
14
14
  from plain.models.db import db_connection
15
15
  from plain.models.enums import ChoicesMeta
16
16
  from plain.models.query_utils import DeferredAttribute, RegisterLookupMixin
17
+ from plain.preflight import PreflightResult
17
18
  from plain.utils import timezone
18
19
  from plain.utils.datastructures import DictWrapper
19
20
  from plain.utils.dateparse import (
@@ -36,7 +37,6 @@ __all__ = [
36
37
  "BinaryField",
37
38
  "BooleanField",
38
39
  "CharField",
39
- "CommaSeparatedIntegerField",
40
40
  "DateField",
41
41
  "DateTimeField",
42
42
  "DecimalField",
@@ -46,10 +46,8 @@ __all__ = [
46
46
  "Field",
47
47
  "FloatField",
48
48
  "GenericIPAddressField",
49
- "IPAddressField",
50
49
  "IntegerField",
51
50
  "NOT_PROVIDED",
52
- "NullBooleanField",
53
51
  "PositiveBigIntegerField",
54
52
  "PositiveIntegerField",
55
53
  "PositiveSmallIntegerField",
@@ -125,8 +123,6 @@ class Field(RegisterLookupMixin):
125
123
  "required": "This field is be required.",
126
124
  "unique": "A %(model_name)s with this %(field_label)s already exists.",
127
125
  }
128
- system_check_deprecated_details = None
129
- system_check_removed_details = None
130
126
 
131
127
  # Attributes that don't affect a column definition.
132
128
  # These attributes are ignored when altering the field.
@@ -218,15 +214,14 @@ class Field(RegisterLookupMixin):
218
214
  return f"<{path}: {name}>"
219
215
  return f"<{path}>"
220
216
 
221
- def check(self, **kwargs):
217
+ def preflight(self, **kwargs):
222
218
  return [
223
219
  *self._check_field_name(),
224
220
  *self._check_choices(),
225
- *self._check_db_comment(**kwargs),
221
+ *self._check_db_comment(),
226
222
  *self._check_null_allowed_for_primary_keys(),
227
- *self._check_backend_specific_checks(**kwargs),
223
+ *self._check_backend_specific_checks(),
228
224
  *self._check_validators(),
229
- *self._check_deprecation_details(),
230
225
  ]
231
226
 
232
227
  def _check_field_name(self):
@@ -236,26 +231,26 @@ class Field(RegisterLookupMixin):
236
231
  """
237
232
  if self.name.endswith("_"):
238
233
  return [
239
- preflight.Error(
240
- "Field names must not end with an underscore.",
234
+ PreflightResult(
235
+ fix="Field names must not end with an underscore.",
241
236
  obj=self,
242
- id="fields.E001",
237
+ id="fields.name_ends_with_underscore",
243
238
  )
244
239
  ]
245
240
  elif LOOKUP_SEP in self.name:
246
241
  return [
247
- preflight.Error(
248
- f'Field names must not contain "{LOOKUP_SEP}".',
242
+ PreflightResult(
243
+ fix=f'Field names must not contain "{LOOKUP_SEP}".',
249
244
  obj=self,
250
- id="fields.E002",
245
+ id="fields.name_contains_lookup_separator",
251
246
  )
252
247
  ]
253
248
  elif self.name == "id":
254
249
  return [
255
- preflight.Error(
256
- "'id' is a reserved word that cannot be used as a field name.",
250
+ PreflightResult(
251
+ fix="'id' is a reserved word that cannot be used as a field name.",
257
252
  obj=self,
258
- id="fields.E003",
253
+ id="fields.reserved_field_name_id",
259
254
  )
260
255
  ]
261
256
  else:
@@ -271,10 +266,10 @@ class Field(RegisterLookupMixin):
271
266
 
272
267
  if not is_iterable(self.choices) or isinstance(self.choices, str):
273
268
  return [
274
- preflight.Error(
275
- "'choices' must be an iterable (e.g., a list or tuple).",
269
+ PreflightResult(
270
+ fix="'choices' must be an iterable (e.g., a list or tuple).",
276
271
  obj=self,
277
- id="fields.E004",
272
+ id="fields.choices_not_iterable",
278
273
  )
279
274
  ]
280
275
 
@@ -319,26 +314,26 @@ class Field(RegisterLookupMixin):
319
314
  else:
320
315
  if self.max_length is not None and choice_max_length > self.max_length:
321
316
  return [
322
- preflight.Error(
323
- "'max_length' is too small to fit the longest value " # noqa: UP031
317
+ PreflightResult(
318
+ fix="'max_length' is too small to fit the longest value " # noqa: UP031
324
319
  "in 'choices' (%d characters)." % choice_max_length,
325
320
  obj=self,
326
- id="fields.E009",
321
+ id="fields.max_length_too_small_for_choices",
327
322
  ),
328
323
  ]
329
324
  return []
330
325
 
331
326
  return [
332
- preflight.Error(
333
- "'choices' must be an iterable containing "
327
+ PreflightResult(
328
+ fix="'choices' must be an iterable containing "
334
329
  "(actual value, human readable name) tuples.",
335
330
  obj=self,
336
- id="fields.E005",
331
+ id="fields.choices_invalid_format",
337
332
  )
338
333
  ]
339
334
 
340
- def _check_db_comment(self, database=False, **kwargs):
341
- if not self.db_comment or not database:
335
+ def _check_db_comment(self):
336
+ if not self.db_comment:
342
337
  return []
343
338
  errors = []
344
339
  if not (
@@ -346,11 +341,12 @@ class Field(RegisterLookupMixin):
346
341
  or "supports_comments" in self.model._meta.required_db_features
347
342
  ):
348
343
  errors.append(
349
- preflight.Warning(
350
- f"{db_connection.display_name} does not support comments on "
344
+ PreflightResult(
345
+ fix=f"{db_connection.display_name} does not support comments on "
351
346
  f"columns (db_comment).",
352
347
  obj=self,
353
- id="fields.W163",
348
+ id="fields.db_comment_unsupported",
349
+ warning=True,
354
350
  )
355
351
  )
356
352
  return errors
@@ -361,24 +357,20 @@ class Field(RegisterLookupMixin):
361
357
  # consider NULL and '' to be equal (and thus set up
362
358
  # character-based fields a little differently).
363
359
  return [
364
- preflight.Error(
365
- "Primary keys must not have allow_null=True.",
366
- hint=(
367
- "Set allow_null=False on the field, or "
368
- "remove primary_key=True argument."
369
- ),
360
+ PreflightResult(
361
+ fix="Primary keys must not have allow_null=True. "
362
+ "Set allow_null=False on the field, or "
363
+ "remove primary_key=True argument.",
370
364
  obj=self,
371
- id="fields.E007",
365
+ id="fields.primary_key_allows_null",
372
366
  )
373
367
  ]
374
368
  else:
375
369
  return []
376
370
 
377
- def _check_backend_specific_checks(self, database=False, **kwargs):
378
- if not database:
379
- return []
371
+ def _check_backend_specific_checks(self):
380
372
  errors = []
381
- errors.extend(db_connection.validation.check_field(self, **kwargs))
373
+ errors.extend(db_connection.validation.check_field(self))
382
374
  return errors
383
375
 
384
376
  def _check_validators(self):
@@ -386,45 +378,18 @@ class Field(RegisterLookupMixin):
386
378
  for i, validator in enumerate(self.validators):
387
379
  if not callable(validator):
388
380
  errors.append(
389
- preflight.Error(
390
- "All 'validators' must be callable.",
391
- hint=(
381
+ PreflightResult(
382
+ fix=(
383
+ "All 'validators' must be callable. "
392
384
  f"validators[{i}] ({repr(validator)}) isn't a function or "
393
385
  "instance of a validator class."
394
386
  ),
395
387
  obj=self,
396
- id="fields.E008",
388
+ id="fields.invalid_validator",
397
389
  )
398
390
  )
399
391
  return errors
400
392
 
401
- def _check_deprecation_details(self):
402
- if self.system_check_removed_details is not None:
403
- return [
404
- preflight.Error(
405
- self.system_check_removed_details.get(
406
- "msg",
407
- f"{self.__class__.__name__} has been removed except for support in historical "
408
- "migrations.",
409
- ),
410
- hint=self.system_check_removed_details.get("hint"),
411
- obj=self,
412
- id=self.system_check_removed_details.get("id", "fields.EXXX"),
413
- )
414
- ]
415
- elif self.system_check_deprecated_details is not None:
416
- return [
417
- preflight.Warning(
418
- self.system_check_deprecated_details.get(
419
- "msg", f"{self.__class__.__name__} has been deprecated."
420
- ),
421
- hint=self.system_check_deprecated_details.get("hint"),
422
- obj=self,
423
- id=self.system_check_deprecated_details.get("id", "fields.WXXX"),
424
- )
425
- ]
426
- return []
427
-
428
393
  def get_col(self, alias, output_field=None):
429
394
  if alias == self.model._meta.db_table and (
430
395
  output_field is None or output_field == self
@@ -985,12 +950,11 @@ class CharField(Field):
985
950
  else:
986
951
  return "String (unlimited)"
987
952
 
988
- def check(self, **kwargs):
989
- database = kwargs.get("database", False)
953
+ def preflight(self, **kwargs):
990
954
  return [
991
- *super().check(**kwargs),
992
- *self._check_db_collation(database),
993
- *self._check_max_length_attribute(**kwargs),
955
+ *super().preflight(**kwargs),
956
+ *self._check_db_collation(),
957
+ *self._check_max_length_attribute(),
994
958
  ]
995
959
 
996
960
  def _check_max_length_attribute(self, **kwargs):
@@ -1002,10 +966,10 @@ class CharField(Field):
1002
966
  ):
1003
967
  return []
1004
968
  return [
1005
- preflight.Error(
1006
- "CharFields must define a 'max_length' attribute.",
969
+ PreflightResult(
970
+ fix="CharFields must define a 'max_length' attribute.",
1007
971
  obj=self,
1008
- id="fields.E120",
972
+ id="fields.charfield_missing_max_length",
1009
973
  )
1010
974
  ]
1011
975
  elif (
@@ -1014,29 +978,29 @@ class CharField(Field):
1014
978
  or self.max_length <= 0
1015
979
  ):
1016
980
  return [
1017
- preflight.Error(
1018
- "'max_length' must be a positive integer.",
981
+ PreflightResult(
982
+ fix="'max_length' must be a positive integer.",
1019
983
  obj=self,
1020
- id="fields.E121",
984
+ id="fields.charfield_invalid_max_length",
1021
985
  )
1022
986
  ]
1023
987
  else:
1024
988
  return []
1025
989
 
1026
- def _check_db_collation(self, database):
990
+ def _check_db_collation(self):
1027
991
  errors = []
1028
- if database and not (
992
+ if not (
1029
993
  self.db_collation is None
1030
994
  or "supports_collation_on_charfield"
1031
995
  in self.model._meta.required_db_features
1032
996
  or db_connection.features.supports_collation_on_charfield
1033
997
  ):
1034
998
  errors.append(
1035
- preflight.Error(
1036
- f"{db_connection.display_name} does not support a database collation on "
999
+ PreflightResult(
1000
+ fix=f"{db_connection.display_name} does not support a database collation on "
1037
1001
  "CharFields.",
1038
1002
  obj=self,
1039
- id="fields.E190",
1003
+ id="fields.db_collation_unsupported",
1040
1004
  ),
1041
1005
  )
1042
1006
  return errors
@@ -1070,21 +1034,6 @@ class CharField(Field):
1070
1034
  return name, path, args, kwargs
1071
1035
 
1072
1036
 
1073
- class CommaSeparatedIntegerField(CharField):
1074
- default_validators = [validators.validate_comma_separated_integer_list]
1075
- description = "Comma-separated integers"
1076
- system_check_removed_details = {
1077
- "msg": (
1078
- "CommaSeparatedIntegerField is removed except for support in "
1079
- "historical migrations."
1080
- ),
1081
- "hint": (
1082
- "Use CharField(validators=[validate_comma_separated_integer_list]) instead."
1083
- ),
1084
- "id": "fields.E901",
1085
- }
1086
-
1087
-
1088
1037
  def _to_naive(value):
1089
1038
  if timezone.is_aware(value):
1090
1039
  value = timezone.make_naive(value, datetime.UTC)
@@ -1096,9 +1045,9 @@ def _get_naive_now():
1096
1045
 
1097
1046
 
1098
1047
  class DateTimeCheckMixin:
1099
- def check(self, **kwargs):
1048
+ def preflight(self, **kwargs):
1100
1049
  return [
1101
- *super().check(**kwargs),
1050
+ *super().preflight(**kwargs),
1102
1051
  *self._check_mutually_exclusive_options(),
1103
1052
  *self._check_fix_default_value(),
1104
1053
  ]
@@ -1117,12 +1066,12 @@ class DateTimeCheckMixin:
1117
1066
  ].count(True)
1118
1067
  if enabled_options > 1:
1119
1068
  return [
1120
- preflight.Error(
1121
- "The options auto_now, auto_now_add, and default "
1069
+ PreflightResult(
1070
+ fix="The options auto_now, auto_now_add, and default "
1122
1071
  "are mutually exclusive. Only one of these options "
1123
1072
  "may be present.",
1124
1073
  obj=self,
1125
- id="fields.E160",
1074
+ id="fields.datetime_auto_options_mutually_exclusive",
1126
1075
  )
1127
1076
  ]
1128
1077
  else:
@@ -1153,16 +1102,15 @@ class DateTimeCheckMixin:
1153
1102
  upper = upper.date()
1154
1103
  if lower <= value <= upper:
1155
1104
  return [
1156
- preflight.Warning(
1157
- "Fixed default value provided.",
1158
- hint=(
1159
- "It seems you set a fixed date / time / datetime "
1160
- "value as default for this field. This may not be "
1161
- "what you want. If you want to have the current date "
1162
- "as default, use `plain.utils.timezone.now`"
1163
- ),
1105
+ PreflightResult(
1106
+ fix="Fixed default value provided. "
1107
+ "It seems you set a fixed date / time / datetime "
1108
+ "value as default for this field. This may not be "
1109
+ "what you want. If you want to have the current date "
1110
+ "as default, use `plain.utils.timezone.now`",
1164
1111
  obj=self,
1165
- id="fields.W161",
1112
+ id="fields.datetime_naive_default_value",
1113
+ warning=True,
1166
1114
  )
1167
1115
  ]
1168
1116
  return []
@@ -1422,15 +1370,15 @@ class DecimalField(Field):
1422
1370
  self.max_digits, self.decimal_places = max_digits, decimal_places
1423
1371
  super().__init__(**kwargs)
1424
1372
 
1425
- def check(self, **kwargs):
1426
- errors = super().check(**kwargs)
1373
+ def preflight(self, **kwargs):
1374
+ errors = super().preflight(**kwargs)
1427
1375
 
1428
1376
  digits_errors = [
1429
1377
  *self._check_decimal_places(),
1430
1378
  *self._check_max_digits(),
1431
1379
  ]
1432
1380
  if not digits_errors:
1433
- errors.extend(self._check_decimal_places_and_max_digits(**kwargs))
1381
+ errors.extend(self._check_decimal_places_and_max_digits())
1434
1382
  else:
1435
1383
  errors.extend(digits_errors)
1436
1384
  return errors
@@ -1442,18 +1390,18 @@ class DecimalField(Field):
1442
1390
  raise ValueError()
1443
1391
  except TypeError:
1444
1392
  return [
1445
- preflight.Error(
1446
- "DecimalFields must define a 'decimal_places' attribute.",
1393
+ PreflightResult(
1394
+ fix="DecimalFields must define a 'decimal_places' attribute.",
1447
1395
  obj=self,
1448
- id="fields.E130",
1396
+ id="fields.decimalfield_missing_decimal_places",
1449
1397
  )
1450
1398
  ]
1451
1399
  except ValueError:
1452
1400
  return [
1453
- preflight.Error(
1454
- "'decimal_places' must be a non-negative integer.",
1401
+ PreflightResult(
1402
+ fix="'decimal_places' must be a non-negative integer.",
1455
1403
  obj=self,
1456
- id="fields.E131",
1404
+ id="fields.decimalfield_invalid_decimal_places",
1457
1405
  )
1458
1406
  ]
1459
1407
  else:
@@ -1466,30 +1414,30 @@ class DecimalField(Field):
1466
1414
  raise ValueError()
1467
1415
  except TypeError:
1468
1416
  return [
1469
- preflight.Error(
1470
- "DecimalFields must define a 'max_digits' attribute.",
1417
+ PreflightResult(
1418
+ fix="DecimalFields must define a 'max_digits' attribute.",
1471
1419
  obj=self,
1472
- id="fields.E132",
1420
+ id="fields.decimalfield_missing_max_digits",
1473
1421
  )
1474
1422
  ]
1475
1423
  except ValueError:
1476
1424
  return [
1477
- preflight.Error(
1478
- "'max_digits' must be a positive integer.",
1425
+ PreflightResult(
1426
+ fix="'max_digits' must be a positive integer.",
1479
1427
  obj=self,
1480
- id="fields.E133",
1428
+ id="fields.decimalfield_invalid_max_digits",
1481
1429
  )
1482
1430
  ]
1483
1431
  else:
1484
1432
  return []
1485
1433
 
1486
- def _check_decimal_places_and_max_digits(self, **kwargs):
1434
+ def _check_decimal_places_and_max_digits(self):
1487
1435
  if int(self.decimal_places) > int(self.max_digits):
1488
1436
  return [
1489
- preflight.Error(
1490
- "'max_digits' must be greater or equal to 'decimal_places'.",
1437
+ PreflightResult(
1438
+ fix="'max_digits' must be greater or equal to 'decimal_places'.",
1491
1439
  obj=self,
1492
- id="fields.E134",
1440
+ id="fields.decimalfield_decimal_places_exceeds_max_digits",
1493
1441
  )
1494
1442
  ]
1495
1443
  return []
@@ -1662,20 +1610,20 @@ class IntegerField(Field):
1662
1610
  }
1663
1611
  description = "Integer"
1664
1612
 
1665
- def check(self, **kwargs):
1613
+ def preflight(self, **kwargs):
1666
1614
  return [
1667
- *super().check(**kwargs),
1615
+ *super().preflight(**kwargs),
1668
1616
  *self._check_max_length_warning(),
1669
1617
  ]
1670
1618
 
1671
1619
  def _check_max_length_warning(self):
1672
1620
  if self.max_length is not None:
1673
1621
  return [
1674
- preflight.Warning(
1675
- f"'max_length' is ignored when used with {self.__class__.__name__}.",
1676
- hint="Remove 'max_length' from field",
1622
+ PreflightResult(
1623
+ fix=f"'max_length' is ignored when used with {self.__class__.__name__}. Remove 'max_length' from field.",
1677
1624
  obj=self,
1678
- id="fields.W122",
1625
+ id="fields.max_length_ignored",
1626
+ warning=True,
1679
1627
  )
1680
1628
  ]
1681
1629
  return []
@@ -1760,37 +1708,6 @@ class SmallIntegerField(IntegerField):
1760
1708
  return "SmallIntegerField"
1761
1709
 
1762
1710
 
1763
- class IPAddressField(Field):
1764
- empty_strings_allowed = False
1765
- description = "IPv4 address"
1766
- system_check_removed_details = {
1767
- "msg": (
1768
- "IPAddressField has been removed except for support in "
1769
- "historical migrations."
1770
- ),
1771
- "hint": "Use GenericIPAddressField instead.",
1772
- "id": "fields.E900",
1773
- }
1774
-
1775
- def __init__(self, **kwargs):
1776
- kwargs["max_length"] = 15
1777
- super().__init__(**kwargs)
1778
-
1779
- def deconstruct(self):
1780
- name, path, args, kwargs = super().deconstruct()
1781
- del kwargs["max_length"]
1782
- return name, path, args, kwargs
1783
-
1784
- def get_prep_value(self, value):
1785
- value = super().get_prep_value(value)
1786
- if value is None:
1787
- return None
1788
- return str(value)
1789
-
1790
- def get_internal_type(self):
1791
- return "IPAddressField"
1792
-
1793
-
1794
1711
  class GenericIPAddressField(Field):
1795
1712
  empty_strings_allowed = False
1796
1713
  description = "IP address"
@@ -1813,22 +1730,22 @@ class GenericIPAddressField(Field):
1813
1730
  kwargs["max_length"] = 39
1814
1731
  super().__init__(**kwargs)
1815
1732
 
1816
- def check(self, **kwargs):
1733
+ def preflight(self, **kwargs):
1817
1734
  return [
1818
- *super().check(**kwargs),
1819
- *self._check_required_and_null_values(**kwargs),
1735
+ *super().preflight(**kwargs),
1736
+ *self._check_required_and_null_values(),
1820
1737
  ]
1821
1738
 
1822
- def _check_required_and_null_values(self, **kwargs):
1739
+ def _check_required_and_null_values(self):
1823
1740
  if not getattr(self, "allow_null", False) and not getattr(
1824
1741
  self, "required", True
1825
1742
  ):
1826
1743
  return [
1827
- preflight.Error(
1828
- "GenericIPAddressFields cannot have required=False if allow_null=False, "
1744
+ PreflightResult(
1745
+ fix="GenericIPAddressFields cannot have required=False if allow_null=False, "
1829
1746
  "as blank values are stored as nulls.",
1830
1747
  obj=self,
1831
- id="fields.E150",
1748
+ id="fields.generic_ip_field_null_blank_config",
1832
1749
  )
1833
1750
  ]
1834
1751
  return []
@@ -1875,32 +1792,6 @@ class GenericIPAddressField(Field):
1875
1792
  return str(value)
1876
1793
 
1877
1794
 
1878
- class NullBooleanField(BooleanField):
1879
- default_error_messages = {
1880
- "invalid": "“%(value)s” value must be either None, True or False.",
1881
- "invalid_nullable": "“%(value)s” value must be either None, True or False.",
1882
- }
1883
- description = "Boolean (Either True, False or None)"
1884
- system_check_removed_details = {
1885
- "msg": (
1886
- "NullBooleanField is removed except for support in historical migrations."
1887
- ),
1888
- "hint": "Use BooleanField(allow_null=True) instead.",
1889
- "id": "fields.E903",
1890
- }
1891
-
1892
- def __init__(self, **kwargs):
1893
- kwargs["allow_null"] = True
1894
- kwargs["required"] = False
1895
- super().__init__(**kwargs)
1896
-
1897
- def deconstruct(self):
1898
- name, path, args, kwargs = super().deconstruct()
1899
- del kwargs["allow_null"]
1900
- del kwargs["required"]
1901
- return name, path, args, kwargs
1902
-
1903
-
1904
1795
  class PositiveIntegerRelDbTypeMixin:
1905
1796
  def __init_subclass__(cls, **kwargs):
1906
1797
  super().__init_subclass__(**kwargs)
@@ -1957,27 +1848,26 @@ class TextField(Field):
1957
1848
  super().__init__(**kwargs)
1958
1849
  self.db_collation = db_collation
1959
1850
 
1960
- def check(self, **kwargs):
1961
- database = kwargs.get("database", False)
1851
+ def preflight(self, **kwargs):
1962
1852
  return [
1963
- *super().check(**kwargs),
1964
- *self._check_db_collation(database),
1853
+ *super().preflight(**kwargs),
1854
+ *self._check_db_collation(),
1965
1855
  ]
1966
1856
 
1967
- def _check_db_collation(self, database):
1857
+ def _check_db_collation(self):
1968
1858
  errors = []
1969
- if database and not (
1859
+ if not (
1970
1860
  self.db_collation is None
1971
1861
  or "supports_collation_on_textfield"
1972
1862
  in self.model._meta.required_db_features
1973
1863
  or db_connection.features.supports_collation_on_textfield
1974
1864
  ):
1975
1865
  errors.append(
1976
- preflight.Error(
1977
- f"{db_connection.display_name} does not support a database collation on "
1866
+ PreflightResult(
1867
+ fix=f"{db_connection.display_name} does not support a database collation on "
1978
1868
  "TextFields.",
1979
1869
  obj=self,
1980
- id="fields.E190",
1870
+ id="fields.db_collation_unsupported",
1981
1871
  ),
1982
1872
  )
1983
1873
  return errors
@@ -2130,17 +2020,17 @@ class BinaryField(Field):
2130
2020
  if self.max_length is not None:
2131
2021
  self.validators.append(validators.MaxLengthValidator(self.max_length))
2132
2022
 
2133
- def check(self, **kwargs):
2134
- return [*super().check(**kwargs), *self._check_str_default_value()]
2023
+ def preflight(self, **kwargs):
2024
+ return [*super().preflight(**kwargs), *self._check_str_default_value()]
2135
2025
 
2136
2026
  def _check_str_default_value(self):
2137
2027
  if self.has_default() and isinstance(self.default, str):
2138
2028
  return [
2139
- preflight.Error(
2140
- "BinaryField's default cannot be a string. Use bytes "
2029
+ PreflightResult(
2030
+ fix="BinaryField's default cannot be a string. Use bytes "
2141
2031
  "content instead.",
2142
2032
  obj=self,
2143
- id="fields.E170",
2033
+ id="fields.filefield_upload_to_not_callable",
2144
2034
  )
2145
2035
  ]
2146
2036
  return []
@@ -2236,10 +2126,10 @@ class PrimaryKeyField(BigIntegerField):
2236
2126
  self.creation_counter = Field.auto_creation_counter
2237
2127
  Field.auto_creation_counter -= 1
2238
2128
 
2239
- def check(self, **kwargs):
2240
- errors = super().check(**kwargs)
2241
- # Remove the E003 error for 'id' field name since PrimaryKeyField is allowed to use it
2242
- errors = [e for e in errors if e.id != "fields.E003"]
2129
+ def preflight(self, **kwargs):
2130
+ errors = super().preflight(**kwargs)
2131
+ # Remove the reserved_field_name_id error for 'id' field name since PrimaryKeyField is allowed to use it
2132
+ errors = [e for e in errors if e.id != "fields.reserved_field_name_id"]
2243
2133
  return errors
2244
2134
 
2245
2135
  def deconstruct(self):