1import collections.abc
2import copy
3import enum
4from collections.abc import Callable, Iterable, Sequence
5from functools import cached_property
6from typing import (
7 TYPE_CHECKING,
8 Any,
9 Self,
10 cast,
11 overload,
12)
13
14from plain.postgres.constants import LOOKUP_SEP
15from plain.postgres.dialect import quote_name
16from plain.postgres.enums import ChoicesMeta
17from plain.postgres.query_utils import Q, RegisterLookupMixin
18from plain.postgres.selectable import Selectable
19from plain.preflight import PreflightResult
20from plain.utils.datastructures import DictWrapper
21from plain.utils.functional import Promise
22from plain.utils.itercompat import is_iterable
23
24from plain import exceptions, validators
25
26from ..registry import models_registry
27
28if TYPE_CHECKING:
29 from plain.postgres.base import Model
30 from plain.postgres.connection import DatabaseConnection
31 from plain.postgres.expressions import Col, Combinable, Func
32 from plain.postgres.fields.reverse_related import ForeignObjectRel
33 from plain.postgres.sql.compiler import SQLCompiler
34
35
36class NOT_PROVIDED:
37 pass
38
39
40class DatabaseDefault:
41 """Sentinel assigned to a field attribute when the column's persistent
42 DEFAULT (e.g. `create_now=True`, `generate=True`) should produce the
43 value on the next INSERT. The INSERT compiler recognizes the sentinel
44 and emits `DEFAULT` in the VALUES clause; RETURNING then populates the
45 real value back onto the instance."""
46
47 def __repr__(self) -> str:
48 return "<DatabaseDefault>"
49
50 def __str__(self) -> str:
51 return "<DatabaseDefault>"
52
53 def __reduce__(self) -> tuple[Any, tuple]:
54 # Pickling/unpickling must round-trip to the same singleton instance;
55 # downstream code uses `value is DATABASE_DEFAULT` identity checks.
56 return (_get_database_default_singleton, ())
57
58
59DATABASE_DEFAULT = DatabaseDefault()
60
61
62def _get_database_default_singleton() -> DatabaseDefault:
63 return DATABASE_DEFAULT
64
65
66# The values to use for "blank" in SelectFields. Will be appended to the start
67# of most "choices" lists.
68BLANK_CHOICE_DASH = [("", "---------")]
69
70
71def _load_field(
72 package_label: str, model_name: str, field_name: str
73) -> Field[Any] | ForeignObjectRel:
74 return models_registry.get_model(package_label, model_name)._model_meta.get_field(
75 field_name
76 )
77
78
79# A guide to Field parameters:
80#
81# * name: The name of the field specified in the model. This is also the
82# attribute and instance __dict__ key for the field's value -- a
83# foreign key stores its raw key under the field name and is
84# reached through its descriptor.
85# * column: The database column for this field. The same as "name",
86# except for ForeignKeys, where the "_id" suffix is appended.
87
88
89def _empty(of_cls: type) -> Any:
90 """Build an initialized-but-unpopulated instance of `of_cls`.
91
92 Module-level (not a lambda or a method) because `__reduce__` names it as
93 the pickle reconstructor.
94 """
95 return object.__new__(of_cls)
96
97
98# Ordering conditions: the ones a None operand is meaningless for.
99_ORDERING_SUFFIXES = frozenset({"gt", "gte", "lt", "lte"})
100
101# The two lookups `.is_in()` can build: `any_of` for a collection of values,
102# `in` for a queryset. Both take a collection, so both need the string guard.
103_IS_IN_SUFFIXES = frozenset({"in", "any_of"})
104
105
106class Field[T](Selectable[T], RegisterLookupMixin):
107 """Base class for all field types"""
108
109 # SQL type for this field (e.g. "text", "integer", "boolean").
110 # String templates are interpolated against db_type_parameters().
111 # Subclasses that need dynamic logic override db_type() instead.
112 db_type_sql: str | None = None
113 # Column definition suffix (e.g. "GENERATED BY DEFAULT AS IDENTITY").
114 db_type_suffix_sql: str | None = None
115 # SQL type for Cast() expressions. Falls back to db_type() if None.
116 cast_db_type_sql: str | None = None
117
118 # Instance attributes set during field lifecycle
119 # Set by __init__; becomes the real field name once contributed to a
120 # model class (set_attributes_from_name, called by contribute_to_class)
121 name: str
122 # Set by set_attributes_from_name (called by contribute_to_class)
123 column: str
124 # Set by contribute_to_class
125 model: type[Model]
126
127 # Designates whether empty strings fundamentally are allowed at the
128 # database level.
129 empty_strings_allowed = True
130 # Whether what the field holds is a secret: a password's hash, a value
131 # kept encrypted. A model instance printed in a failed test's report is
132 # printed without it. A field type outside this package that holds one
133 # sets this to True.
134 value_is_secret = False
135 empty_values = tuple(validators.EMPTY_VALUES)
136
137 default_validators: tuple[
138 Callable[[Any], None], ...
139 ] = () # Default set of validators
140 unique_error_message = "A %(model_name)s with this %(field_label)s already exists."
141
142 # Kwargs that don't affect the column definition; the schema editor
143 # ignores these when deciding whether an ALTER is needed. Subclasses
144 # that introduce additional non-db kwargs extend this tuple.
145 non_migration_attrs: tuple[str, ...] = ()
146
147 def __init__(self) -> None:
148 self.name = "" # Set by set_attributes_from_name
149 self.primary_key = False
150 self.auto_created = False
151
152 def __str__(self) -> str:
153 """
154 Return "package_label.model_label.field_name" for fields attached to
155 models.
156 """
157 if self.is_lookup_reference:
158 return f"{self.name} (lookup reference)"
159 if not hasattr(self, "model"):
160 return super().__str__()
161 model = self.model
162 return f"{model.model_options.label}.{self.name}"
163
164 def __repr__(self) -> str:
165 """Display the module, class, and name of the field."""
166 path = f"{self.__class__.__module__}.{self.__class__.__qualname__}"
167 name = getattr(self, "name", "")
168 if self.is_lookup_reference:
169 return f"<{path} lookup reference: {name}>"
170 if name:
171 return f"<{path}: {name}>"
172 return f"<{path}>"
173
174 # Typed query conditions. Available on every field; subclasses extend
175 # with type-specific lookups (comparison on numeric, string ops on text).
176 # The names are listed once in CONDITION_METHODS below -- anything that
177 # needs the set (traversal advice, tests) imports it rather than retyping.
178 # The comparisons take a value, another column of the same value type, or
179 # an expression. `Field[T]` is what makes `retry_attempt.lt(retries)` the
180 # typed spelling of `filter(retry_attempt__lt=F("retries"))` -- and, being
181 # parameterized by the same `T`, it rejects a column of another type.
182 #
183 # `Field[T | None]` is the second arm because `Field` is invariant in `T`,
184 # so a nullable column is a different type to the checker and a non-null
185 # one wouldn't otherwise accept it. Only that direction is expressible:
186 # from a nullable left there is no way to name `T` without its `None`, so
187 # `note.equals(name)` is rejected while `name.equals(note)` is accepted.
188 #
189 # `Combinable` is deliberately unconstrained: an expression's output type
190 # isn't tracked, so `priority.lt(F("name"))` type-checks. `F()` is the
191 # untyped escape hatch here exactly as it is in `filter()`, and narrowing
192 # it would mean typing expressions first.
193 def equals(self, value: T | Field[T] | Field[T | None] | Combinable) -> Q:
194 return self._build_q("equals", "", value)
195
196 def not_equal(self, value: T | Field[T] | Field[T | None] | Combinable) -> Q:
197 return ~self._build_q("not_equal", "", value)
198
199 def gt(self, value: T | Field[T] | Field[T | None] | Combinable) -> Q:
200 return self._build_q("gt", "gt", value)
201
202 def gte(self, value: T | Field[T] | Field[T | None] | Combinable) -> Q:
203 return self._build_q("gte", "gte", value)
204
205 def lt(self, value: T | Field[T] | Field[T | None] | Combinable) -> Q:
206 return self._build_q("lt", "lt", value)
207
208 def lte(self, value: T | Field[T] | Field[T | None] | Combinable) -> Q:
209 return self._build_q("lte", "lte", value)
210
211 def is_null(self, value: bool = True) -> Q:
212 return self._build_q("is_null", "isnull", value)
213
214 def is_in(self, values: Iterable[T]) -> Q:
215 """Match rows whose value is one of `values`.
216
217 A plain collection binds as a single array parameter --
218 `"col" = ANY(%s::text[])` -- so the statement has the same shape for
219 any number of values, an empty list included. A queryset stays a
220 subquery: `"col" IN (SELECT ...)`.
221
222 A None in the collection raises `ValueError`: NULL is not a value a
223 comparison can match, so it belongs in `is_null()`, not here.
224 """
225 from plain.postgres.query import QuerySet
226 from plain.postgres.sql.query import Query
227
228 if isinstance(values, QuerySet | Query):
229 return self._build_q("is_in", "in", values)
230 return self._build_q("is_in", "any_of", values)
231
232 # Pattern conditions. They live on Field, like every other condition, so
233 # they survive the `Field[T]` annotation models carry -- a field's declared
234 # type is `Field[str]`, not `TextField[str]`, so the checker only ever sees
235 # what `Field` offers. The `self` annotation is the restriction: a
236 # `Field[int]` rejects `.startswith(...)` statically, and `_build_q`
237 # rejects it at runtime for anything that doesn't register the lookup.
238 #
239 # (`JSONField` does register a jsonb `contains`, so `Field[dict].contains`
240 # is rejected by the `self` type rather than at runtime -- the same
241 # type-first guard the encrypted fields use.)
242 def contains(self: Field[str] | Field[str | None], value: str) -> Q:
243 return self._build_q("contains", "contains", value)
244
245 def icontains(self: Field[str] | Field[str | None], value: str) -> Q:
246 return self._build_q("icontains", "icontains", value)
247
248 def startswith(self: Field[str] | Field[str | None], value: str) -> Q:
249 return self._build_q("startswith", "startswith", value)
250
251 def endswith(self: Field[str] | Field[str | None], value: str) -> Q:
252 return self._build_q("endswith", "endswith", value)
253
254 # The case-insensitive halves. `iequals` is named for the condition it is
255 # (`equals`, ignoring case) rather than for the `iexact` lookup it builds --
256 # there is no `exact` condition method for it to pair with.
257 def iequals(self: Field[str] | Field[str | None], value: str) -> Q:
258 return self._build_q("iequals", "iexact", value)
259
260 def istartswith(self: Field[str] | Field[str | None], value: str) -> Q:
261 return self._build_q("istartswith", "istartswith", value)
262
263 def iendswith(self: Field[str] | Field[str | None], value: str) -> Q:
264 return self._build_q("iendswith", "iendswith", value)
265
266 def _build_q(self, method: str, suffix: str, value: Any) -> Q:
267 """Build a Q from a lookup suffix + value. Uses Q's positional-tuple
268 constructor to bypass its reserved `_connector`/`_negated` kwargs that
269 confuse the type checker on `**{name: value}` expansion.
270
271 `method` is the condition method's own name, used only for error
272 messages -- it's what the caller wrote, so it's what an error should
273 name.
274 """
275 assert self.name, (
276 "Field name must be set before building a query condition; "
277 "the field must be attached to a model."
278 )
279 if value is None and suffix in _ORDERING_SUFFIXES:
280 # On a nullable field `T` includes None, so `age.gte(None)` gets
281 # past the type checker -- there is no way to subtract None from a
282 # TypeVar, so `self: Field[X | None], value: X` still solves X as
283 # `int | None` under both ty and pyright. Refuse here instead, at
284 # the call site, rather than letting it reach the compiler as a
285 # "Cannot use None as a query value" ValueError with no field in it.
286 raise TypeError(
287 f"{type(self).__name__} {self.name!r}: .{method}() has no "
288 f"meaning for None -- a SQL comparison against NULL is never "
289 f"true. Use .is_null() instead."
290 )
291 if suffix in _IS_IN_SUFFIXES and isinstance(value, str | bytes):
292 # `Iterable[T]` is satisfied by `str` when T is `str`, and `str` is
293 # a `Sequence[str]`, so there is no way to exclude it statically.
294 # Left alone it iterates characters and silently matches the wrong
295 # rows.
296 raise TypeError(
297 f"{type(self).__name__} {self.name!r}: .is_in() takes a "
298 f"collection of values, not a single {type(value).__name__}. "
299 f"Pass a list -- .is_in([{value!r}])."
300 )
301 if suffix == "any_of":
302 # Materialise once, here. A set or a generator is handed straight
303 # to `Q`, which is copied, hashed and repr'd on its way to the
304 # compiler -- a generator would be exhausted by the first of those
305 # and bind an empty array.
306 value = list(value)
307 if any(item is None for item in value):
308 # Neither of the two things a None could mean is honest.
309 # Matching it means comparing against NULL, which is never
310 # true; dropping it silently changes what the caller asked
311 # for, and the negation is worse -- `NOT (col = ANY(ARRAY[1,
312 # NULL]))` is unknown for every row, so `~is_in([1, None])`
313 # would match nothing at all. Say so instead.
314 raise ValueError(
315 f"{type(self).__name__} {self.name!r}: .is_in() does not "
316 f"accept None -- a SQL comparison against NULL is never "
317 f"true, so a None in the list matches nothing and, "
318 f"negated, excludes every row. Use .is_null() instead, or "
319 f"combine the two for both: "
320 f"field.is_in([...]) | field.is_null()."
321 )
322 if suffix and not self.get_lookup(suffix):
323 # The type checker rejects most of these already (a `Field[int]`
324 # has no `.startswith`); this catches what it can't see.
325 raise TypeError(
326 f"{type(self).__name__} {self.name!r} does not support "
327 f".{method}() -- no {suffix!r} lookup is registered for it."
328 )
329 other_column = value if isinstance(value, Field) else None
330 if other_column is not None:
331 # Comparing against another column. Everything above guards the
332 # left-hand field; the right-hand one gets its own say here.
333 other_column.check_usable_as_comparison_column(method)
334 # `F(name)` is the reference the ORM already understands, and a
335 # traversed field's `name` carries its relation prefix, so this is
336 # the whole conversion.
337 from plain.postgres.expressions import F
338
339 value = F(other_column.name)
340 name = f"{self.name}{LOOKUP_SEP}{suffix}" if suffix else self.name
341 q = Q((name, value))
342 # Which model's where() this condition belongs to, and the field that
343 # built it. See `Q._condition_origins`. A column comparison records
344 # both sides, so a right-hand column from another model is caught the
345 # same way a left-hand one is.
346 origins = set()
347 if source := self.source_model:
348 origins.add((source, self.name))
349 if other_column is not None and (source := other_column.source_model):
350 origins.add((source, other_column.name))
351 if origins:
352 q._condition_origins = frozenset(origins)
353 return q
354
355 def check_usable_as_comparison_column(self, method: str) -> None:
356 """Hook for a field used as the *right-hand* column of a comparison.
357
358 A no-op for an ordinary column. `EncryptedField` overrides it to
359 refuse: its own block lives in `_build_q`, which only ever runs on the
360 field the condition was built *from*, and the type checker can't help
361 either -- `EncryptedField[str]` is a `Field[str]`, so it satisfies
362 `equals`'s `Field[T]` arm like any other string column.
363
364 `method` is the condition the caller wrote on the left-hand field, so
365 a refusal can name it.
366 """
367
368 def with_lookup_prefix(self, prefix: str, source_model: type[Model]) -> Self:
369 """Return a detached copy of this field whose name carries `prefix`.
370
371 This is all where() traversal needs: `Child.parent.name` hands back the
372 related model's own `name` field renamed to `parent__name`, so the
373 field's own condition methods build `Q(parent__name=...)`. Nothing has
374 to re-implement or rewrite the field's surface, which is why a
375 traversed field offers exactly what direct access offers -- including
376 an encrypted field's blocks, whose error message names the full path.
377
378 The copy is genuinely detached: it keeps only what building a Q needs
379 (its class, for the lookup registry, and its name). The attachment
380 state a real field carries is dropped, so it can't pass itself off as
381 a column on the related model -- `str()` would otherwise report
382 `examples.DeleteParent.parent__name`, and `__reduce__` would try to
383 look up an attribute that doesn't exist.
384
385 `source_model` is the model the traversal *started* from, which is the
386 one a condition built here belongs to: `Order.user.email` is a
387 condition for `Order.query.where()`, not `User.query.where()`. It is
388 kept separately from `model` precisely because `model` is dropped.
389 """
390 prefixed = copy.copy(self)
391 for attached in ("model", "column", "cached_col"):
392 prefixed.__dict__.pop(attached, None)
393 prefixed.name = f"{prefix}{LOOKUP_SEP}{self.name}"
394 prefixed.__dict__["_is_lookup_reference"] = True
395 prefixed.__dict__["_source_model"] = source_model
396 return prefixed
397
398 @property
399 def source_model(self) -> type[Model] | None:
400 """The model a condition built from this field belongs to.
401
402 For an attached field that is the model it was declared on. For a
403 traversed copy it is the root the traversal started from, not the
404 related model the column lives on. A detached field (one built for an
405 aggregate, never attached) has neither, and conditions from it go
406 unchecked.
407 """
408 if source := self.__dict__.get("_source_model"):
409 return source
410 return self.__dict__.get("model")
411
412 @property
413 def is_lookup_reference(self) -> bool:
414 """True for a field handed back by `with_lookup_prefix` -- a reference
415 to a column reached through a relation, not a column on a model."""
416 return bool(self.__dict__.get("_is_lookup_reference"))
417
418 @property
419 def lookup_path(self) -> str:
420 """The path this field is reached by in a lookup -- the part before the
421 suffix in `Q(**{f"{field.lookup_path}__icontains": value})`.
422
423 `"email"` for a column on the model, `"user__email"` for one reached by
424 traversal (`Order.user.email`), which is why generic code that has to
425 build a string lookup, an `order_by()` term or a `values()` key from a
426 field reference reads this rather than assembling a path itself.
427
428 It is the field's `name`: `with_lookup_prefix` renames a traversed copy
429 to its full path precisely so the field's own condition methods build
430 the right `Q`. This is the sanctioned spelling of that fact.
431 """
432 return self.name
433
434 def preflight(self, **kwargs: Any) -> list[PreflightResult]:
435 return [*self._check_field_name()]
436
437 def _check_field_name(self) -> list[PreflightResult]:
438 """
439 Check if field name is valid, i.e. 1) does not end with an
440 underscore, 2) does not contain "__" and 3) is not "id".
441 """
442 if self.name.endswith("_"):
443 return [
444 PreflightResult(
445 fix="Field names must not end with an underscore.",
446 obj=self,
447 id="fields.name_ends_with_underscore",
448 )
449 ]
450 elif LOOKUP_SEP in self.name:
451 return [
452 PreflightResult(
453 fix=f'Field names must not contain "{LOOKUP_SEP}".',
454 obj=self,
455 id="fields.name_contains_lookup_separator",
456 )
457 ]
458 elif self.name == "id":
459 return [
460 PreflightResult(
461 fix="'id' is a reserved word that cannot be used as a field name.",
462 obj=self,
463 id="fields.reserved_field_name_id",
464 )
465 ]
466 else:
467 return []
468
469 def get_col(self, alias: str | None, output_field: Field | None = None) -> Col:
470 if alias == self.model.model_options.db_table and (
471 output_field is None or output_field == self
472 ):
473 return self.cached_col
474 from plain.postgres.expressions import Col
475
476 return Col(alias, self, output_field)
477
478 @cached_property
479 def cached_col(self) -> Col:
480 from plain.postgres.expressions import Col
481
482 return Col(self.model.model_options.db_table, self)
483
484 def select_format(
485 self, compiler: SQLCompiler, sql: str, params: Any
486 ) -> tuple[str, Any]:
487 """
488 Custom format for select clauses.
489 """
490 return sql, params
491
492 def deconstruct(self) -> tuple[str, str, list[Any], dict[str, Any]]:
493 """
494 Return enough information to recreate the field as a 4-tuple:
495
496 * The name of the field on the model, if contribute_to_class() has
497 been run.
498 * The import path of the field, including the class, e.g.
499 plain.postgres.IntegerField. This should be the most portable
500 version, so less specific may be better.
501 * A list of positional arguments.
502 * A dict of keyword arguments.
503
504 Note that the positional or keyword arguments must contain values of
505 the following types (including inner values of collection types):
506
507 * None, bool, str, int, float, complex, set, frozenset, list, tuple,
508 dict
509 * UUID
510 * datetime.datetime (naive), datetime.date
511 * top-level classes, top-level functions - will be referenced by their
512 full import path
513 * Storage instances - these have their own deconstruct() method
514
515 This is because the values here must be serialized into a text format
516 (possibly new Python code, possibly JSON) and these are the only types
517 with encoding handlers defined.
518
519 There's no need to return the exact way the field was instantiated this
520 time, just ensure that the resulting field is the same - prefer keyword
521 arguments over positional ones, and omit parameters with their default
522 values.
523 """
524 keywords: dict[str, Any] = {}
525 path = f"{self.__class__.__module__}.{self.__class__.__qualname__}"
526 # Shorten `plain.postgres.fields.<submod>.X` to `plain.postgres.X`
527 # when the class is re-exported at the top-level `plain.postgres`
528 # namespace. The real submodule (`plain.postgres.fields.text`) is
529 # importable but the shortened form is what migration files use.
530 if path.startswith("plain.postgres.fields."):
531 import plain.postgres as _postgres_root
532
533 cls_name = self.__class__.__qualname__
534 if getattr(_postgres_root, cls_name, None) is self.__class__:
535 path = f"plain.postgres.{cls_name}"
536 return (self.name, path, [], keywords)
537
538 def clone(self) -> Self:
539 """
540 Uses deconstruct() to clone a new copy of this Field.
541 Will not preserve any class attachments/attribute names.
542 """
543 _name, _path, args, kwargs = self.deconstruct()
544 return self.__class__(*args, **kwargs)
545
546 def __deepcopy__(self, memodict: dict[int, Any]) -> Self:
547 # We don't have to deepcopy very much here, since most things are not
548 # intended to be altered after initial creation.
549 obj = copy.copy(self)
550 memodict[id(self)] = obj
551 return obj
552
553 def __copy__(self) -> Self:
554 # Build the instance directly rather than calling the constructor,
555 # which would hit __reduce__.
556 obj = object.__new__(self.__class__)
557 obj.__dict__ = self.__dict__.copy()
558 return obj
559
560 def __reduce__(
561 self,
562 ) -> (
563 tuple[Callable[..., Any], tuple[Any, ...], dict[str, Any]]
564 | tuple[Callable[..., Field[Any] | ForeignObjectRel], tuple[str, str, str]]
565 ):
566 """
567 Pickling should return the model._model_meta.fields instance of the field,
568 not a new copy of that field. So, use the app registry to load the
569 model and then the field back.
570 """
571 model = getattr(self, "model", None)
572 if model is None:
573 # Fields are sometimes used without attaching them to models (for
574 # example in aggregation). In this case give back a plain field
575 # instance. The code below will create a new empty instance of
576 # class self.__class__, then update its dict with self.__dict__
577 # values - so, this is very close to normal pickle.
578 state = self.__dict__.copy()
579 return _empty, (self.__class__,), state
580 options = model.model_options
581 return _load_field, (
582 options.package_label,
583 options.object_name,
584 self.name,
585 )
586
587 def to_python(self, value: Any) -> T | None:
588 """
589 Convert the input value into the expected Python data type, raising
590 plain.exceptions.ValidationError if the data can't be converted.
591 Return the converted value. Subclasses should override this.
592 """
593 return value
594
595 def db_type_parameters(self) -> DictWrapper:
596 return DictWrapper(self.__dict__, quote_name, "qn_")
597
598 def db_type(self) -> str | None:
599 """Return the database column data type for this field."""
600 if self.db_type_sql is None:
601 return None
602 return self.db_type_sql % self.db_type_parameters()
603
604 def unqualified_db_type(self) -> str | None:
605 # Uninterpolated so that parameter-only changes (e.g. `max_length`)
606 # aren't flagged as data type changes by ALTER FIELD.
607 if self.db_type_sql is not None:
608 return self.db_type_sql
609 return self.db_type()
610
611 def rel_db_type(self) -> str | None:
612 """
613 Return the data type that a related field pointing to this field should
614 use. For example, this method is called by ForeignKeyField to determine its data type.
615 """
616 return self.db_type()
617
618 def cast_db_type(self) -> str | None:
619 """Return the data type to use in the Cast() function."""
620 if self.cast_db_type_sql is not None:
621 return self.cast_db_type_sql % self.db_type_parameters()
622 return self.db_type()
623
624 def db_type_suffix(self) -> str | None:
625 return self.db_type_suffix_sql
626
627 def get_db_converters(
628 self, connection: DatabaseConnection
629 ) -> list[Callable[..., Any]]:
630 if from_db_value := getattr(self, "from_db_value", None):
631 return [from_db_value]
632 return []
633
634 @property
635 def db_returning(self) -> bool:
636 """True when the column produces a value that RETURNING should fetch
637 back (DB-expression default, identity column, etc.)."""
638 return self.has_db_default()
639
640 @property
641 def auto_fills_on_save(self) -> bool:
642 """True when pre_save populates the field's value at save time
643 (e.g. DateTimeField(update_now=True)). full_clean skips these so the
644 None-before-save doesn't fail nullability/required checks."""
645 return False
646
647 def set_attributes_from_name(self, name: str) -> None:
648 self.name = self.name or name
649 # The database column is the field name. A foreign key overrides this
650 # method only to append the "_id" suffix to `column`.
651 self.column = self.name
652
653 def contribute_to_class(self, cls: type[Model], name: str) -> None:
654 """
655 Register the field with the model class it belongs to.
656
657 Field now acts as its own descriptor - it stays on the class and handles
658 __get__/__set__/__delete__ directly.
659 """
660 self.set_attributes_from_name(name)
661 self.model = cls
662 cls._model_meta.add_field(self)
663
664 # Field is its own descriptor; make sure it is set on the class so
665 # attribute access hits __get__/__set__.
666 if self.column:
667 setattr(cls, self.name, self)
668
669 # Descriptor protocol implementation
670 #
671 # The first overload is class access on a *model-valued* field -- a foreign
672 # key, nullable or not. It yields `type[T]` rather than the descriptor so
673 # the related model's own typed field surface is reachable for where()
674 # traversal (`Child.parent.name.equals(...)`), matching the traversal
675 # `ForwardForeignKeyDescriptor.__getattr__` serves at runtime. It comes
676 # first so it wins over the plain `Self` overload for FK fields; a
677 # non-model T never matches it.
678 @overload
679 def __get__[M: Model](
680 self: Field[M] | Field[M | None], instance: None, owner: type[Model]
681 ) -> type[M]: ...
682
683 @overload
684 def __get__(self, instance: None, owner: type[Model]) -> Self: ...
685
686 @overload
687 def __get__(self, instance: Model, owner: type[Model]) -> T: ...
688
689 def __get__(self, instance: Model | None, owner: type[Model]) -> Self | T:
690 """
691 Descriptor __get__ for attribute access.
692
693 Class access (User.email) returns the Field descriptor itself.
694 Instance access (user.email) returns the field value from instance.__dict__,
695 with lazy loading support if the value is not yet loaded.
696 """
697 # Class access - return the Field descriptor
698 if instance is None:
699 return self
700
701 # If field hasn't been contributed to a class yet (e.g., used standalone
702 # as an output_field in aggregates), just return self
703 if not hasattr(self, "column"):
704 return self
705
706 # Instance access - get value from instance dict
707 data = instance.__dict__
708 field_name = self.name
709
710 # If value not in dict, lazy load from database. Hydrate every
711 # currently-missing concrete field in one query rather than one query
712 # per field accessed -- this is what makes a foreign key partial
713 # instance cheap to use beyond its primary key.
714 if field_name not in data:
715 missing = [
716 f.name for f in instance._model_meta.fields if f.name not in data
717 ]
718 instance.refresh_from_db(fields=missing)
719
720 return cast(T, data.get(field_name))
721
722 def __set__(self, instance: Model, value: T) -> None:
723 """
724 Descriptor __set__ for attribute assignment.
725
726 Validates and converts the value using to_python(), then stores it
727 in instance.__dict__[name].
728
729 The parameter is typed `T` (the field's value type) so a type checker
730 rejects assigning incompatible types — `row.name = 123` on a
731 TextField is caught at the call site. The runtime is more permissive
732 (to_python converts strings → ints etc.), but encouraging explicit
733 conversion at the boundary is the better default.
734 """
735 # Safety check: ensure field has been properly initialized
736 if not hasattr(self, "column"):
737 raise AttributeError(
738 f"Field {self.__class__.__name__} has not been initialized properly. "
739 f"The field's contribute_to_class() has not been called yet. "
740 f"This usually means the field is being used before it was added to a model class."
741 )
742
743 # Convert/validate the value. The DATABASE_DEFAULT sentinel is stored
744 # as-is so the INSERT compiler can emit `DEFAULT` in the VALUES clause.
745 # Use a separate local so the parameter's narrow `T` type isn't
746 # widened by to_python's `T | None` return.
747 stored: Any
748 if value is None or value is DATABASE_DEFAULT:
749 stored = value
750 else:
751 stored = self.to_python(value)
752
753 # Store in instance dict
754 instance.__dict__[self.name] = stored
755
756 def __delete__(self, instance: Model) -> None:
757 """
758 Descriptor __delete__ for attribute deletion.
759
760 Removes the value from instance.__dict__.
761 """
762 try:
763 del instance.__dict__[self.name]
764 except KeyError:
765 raise AttributeError(
766 f"{instance.__class__.__name__!r} object has no attribute {self.name!r}"
767 )
768
769 def pre_save(self, model_instance: Model, add: bool) -> T | None:
770 """Return field's value just before saving."""
771 return getattr(model_instance, self.name)
772
773 def get_prep_value(self, value: Any) -> Any:
774 """Perform preliminary non-db specific value checks and conversions."""
775 if isinstance(value, Promise):
776 value = value._proxy____cast()
777 return value
778
779 def get_db_prep_value(
780 self, value: Any, connection: DatabaseConnection, prepared: bool = False
781 ) -> Any:
782 """
783 Return field's value prepared for interacting with the database backend.
784
785 Used by the default implementations of get_db_prep_save().
786 """
787 if not prepared:
788 value = self.get_prep_value(value)
789 return value
790
791 def get_db_prep_save(self, value: Any, connection: DatabaseConnection) -> Any:
792 """Return field's value prepared for saving into a database."""
793 if hasattr(value, "as_sql"):
794 return value
795 return self.get_db_prep_value(value, connection=connection, prepared=False)
796
797 # Empty-value fallback used by ColumnField.get_default for the
798 # not-null + empty_strings_allowed case (Python-side Model()
799 # construction). BinaryField overrides with b"".
800 _default_empty_value: Any = ""
801
802 # Set to True by validate_none_only_default for the fields that accept
803 # `default=None` without storing it (UUIDField, DateTimeField,
804 # ForeignKeyField, EncryptedJSONField).
805 _declared_default_none: bool = False
806
807 def has_default(self) -> bool:
808 return False
809
810 def has_declared_default(self) -> bool:
811 """Whether the declaration passed ``default=`` at the call site.
812
813 Different question from ``has_default()``, which asks whether a default
814 *value* is stored: the fields validated by ``validate_none_only_default``
815 accept ``default=None`` and store nothing. PEP 681 reads the call site,
816 so both spellings make the field optional in the synthesized
817 constructor.
818 """
819 return self.has_default() or self._declared_default_none
820
821 def has_persistent_literal_default(self) -> bool:
822 return False
823
824 def has_persistent_column_default(self) -> bool:
825 """Whether the column carries a DEFAULT clause that must be preserved
826 (DB-expression default or literal ``default=X``)."""
827 return self.db_returning or self.has_persistent_literal_default()
828
829 def get_db_default_expression(self) -> Func | None:
830 # Return the expression Postgres should evaluate on INSERT (e.g.
831 # Now(), GenRandomUUID()). Subclasses opt in via type-scoped kwargs
832 # (DateTimeField(create_now=True), UUIDField(generate=True)).
833 return None
834
835 def has_db_default(self) -> bool:
836 return self.get_db_default_expression() is not None
837
838 def save_form_data(self, instance: Model, data: Any) -> None:
839 setattr(instance, self.name, data)
840
841 def value_from_object(self, obj: Model) -> T | None:
842 """Return the value of this field in the given model instance."""
843 return getattr(obj, self.name)
844
845
846# The condition methods `Field` exposes, named once. Anything that needs the
847# set rather than the methods themselves -- the relation-traversal advice in
848# related_typed.py, the tests that sweep the surface -- imports from here
849# instead of keeping its own copy in sync.
850#
851# The string conditions come paired with the lookup each one builds. Almost
852# every one is named for its lookup; `iequals` is the exception -- there is no
853# `exact` condition method for an `iexact` to pair with -- so the pairing is
854# written down rather than assumed by whatever needs it.
855STRING_CONDITION_LOOKUPS = {
856 "contains": "contains",
857 "icontains": "icontains",
858 "startswith": "startswith",
859 "endswith": "endswith",
860 "iequals": "iexact",
861 "istartswith": "istartswith",
862 "iendswith": "iendswith",
863}
864STRING_CONDITION_METHODS = tuple(STRING_CONDITION_LOOKUPS)
865CONDITION_METHODS = (
866 "equals",
867 "not_equal",
868 "gt",
869 "gte",
870 "lt",
871 "lte",
872 "is_null",
873 "is_in",
874 *STRING_CONDITION_METHODS,
875)
876
877
878def validate_none_only_default(
879 field: Field[Any], default: Any, *, allow_null: bool
880) -> None:
881 """Enforce the `default=None`-or-nothing contract.
882
883 Some fields can't express a persistent literal column DEFAULT --
884 ColumnField-direct ones (UUIDField, DateTimeField, ForeignKeyField) have no
885 DefaultableField machinery at all, and EncryptedJSONField's ciphertext is
886 non-deterministic. They still accept `default=None` so a nullable variant
887 reads as *optional* in the typed constructor: a stock type checker treats a
888 field as omittable only when its definition passes `default=`. None is the
889 only allowed value and it requires allow_null; the caller stores nothing,
890 because a nullable column already yields None when constructed without a
891 value (see ColumnField.get_default). So `default=None` is purely a typing
892 affordance, and `has_persistent_literal_default()` stays False.
893 """
894 if default is NOT_PROVIDED:
895 return
896 name = type(field).__name__
897 if default is not None:
898 raise TypeError(
899 f"{name} does not accept a persistent default. "
900 "Only default=None is allowed (with allow_null=True), which "
901 "makes the field optional in the constructor."
902 )
903 if not allow_null:
904 raise TypeError(f"{name}(default=None) requires allow_null=True.")
905 # Nothing stores the value, so record that the call site declared it --
906 # that's what `has_declared_default()` (and the preflight check that uses
907 # it) needs to know.
908 field._declared_default_none = True
909
910
911class ColumnField[T](Field[T]):
912 """Base for fields backed by a column value (required/allow_null/validators)."""
913
914 non_migration_attrs = (
915 *Field.non_migration_attrs,
916 "required",
917 "validators",
918 "allow_null",
919 )
920
921 def __init__(
922 self,
923 *,
924 default: Any = NOT_PROVIDED,
925 required: bool = True,
926 allow_null: bool = False,
927 validators: Sequence[Callable[..., Any]] = (),
928 ):
929 validate_none_only_default(self, default, allow_null=allow_null)
930 self.required = required
931 self.allow_null = allow_null
932 self._validators = list(validators)
933 super().__init__()
934
935 def preflight(self, **kwargs: Any) -> list[PreflightResult]:
936 return [
937 *super().preflight(**kwargs),
938 *self._check_null_allowed_for_primary_keys(),
939 *self._check_validators(),
940 ]
941
942 def _check_null_allowed_for_primary_keys(self) -> list[PreflightResult]:
943 if self.primary_key and self.allow_null:
944 return [
945 PreflightResult(
946 fix="Primary keys must not have allow_null=True. "
947 "Set allow_null=False on the field, or "
948 "remove primary_key=True argument.",
949 obj=self,
950 id="fields.primary_key_allows_null",
951 )
952 ]
953 return []
954
955 def _check_validators(self) -> list[PreflightResult]:
956 errors = []
957 for i, validator in enumerate(self.validators):
958 if not callable(validator):
959 errors.append(
960 PreflightResult(
961 fix=(
962 "All 'validators' must be callable. "
963 f"validators[{i}] ({validator!r}) isn't a function or "
964 "instance of a validator class."
965 ),
966 obj=self,
967 id="fields.invalid_validator",
968 )
969 )
970 return errors
971
972 @cached_property
973 def validators(self) -> list[Callable[..., Any]]:
974 # Some validators can't be created at field initialization time;
975 # subclasses (e.g. IntegerField) override to add range validators.
976 return [*self.default_validators, *self._validators]
977
978 def run_validators(self, value: Any) -> None:
979 if value in self.empty_values:
980 return
981 errors = []
982 for v in self.validators:
983 try:
984 v(value)
985 except exceptions.ValidationError as e:
986 errors.extend(e.error_list)
987 if errors:
988 raise exceptions.ValidationError(errors)
989
990 def validate(self, value: Any, model_instance: Model) -> None:
991 if value is None and not self.allow_null:
992 raise exceptions.ValidationError(
993 "This field cannot be null.", code="allow_null"
994 )
995 if self.required and value in self.empty_values:
996 raise exceptions.ValidationError("This field is required.", code="required")
997
998 def clean(self, value: Any, model_instance: Model) -> T | None:
999 value = self.to_python(value)
1000 self.validate(value, model_instance)
1001 self.run_validators(value)
1002 return value
1003
1004 def get_default(self) -> Any:
1005 # Python-side default used when constructing model instances without
1006 # an explicit value. Independent of `required` (validate() catches
1007 # required-but-empty separately). DefaultableField overrides to
1008 # honor a user-provided default.
1009 if not self.empty_strings_allowed or self.allow_null:
1010 return None
1011 return self._default_empty_value
1012
1013 def deconstruct(self) -> tuple[str, str, list[Any], dict[str, Any]]:
1014 name, path, args, kwargs = super().deconstruct()
1015 if self.required is not True:
1016 kwargs["required"] = self.required
1017 if self.allow_null is not False:
1018 kwargs["allow_null"] = self.allow_null
1019 if list(self._validators):
1020 kwargs["validators"] = list(self._validators)
1021 return name, path, args, kwargs
1022
1023
1024class DefaultableField[T](ColumnField[T]):
1025 """Base for column-backed fields that accept a user-provided ``default``."""
1026
1027 non_migration_attrs = (*ColumnField.non_migration_attrs, "default")
1028
1029 # Whether this field can carry a *persistent* column DEFAULT via default=.
1030 # Subclasses that can't (EncryptedJSONField) set this False so callers like
1031 # the autodetector's error guidance don't suggest a kwarg that would raise.
1032 # Note this is only about persistent defaults: a field with this False can
1033 # still accept `default=None`, which stores nothing (see
1034 # validate_none_only_default).
1035 accepts_persistent_default = True
1036
1037 # Subclasses set this when their only expressible column DEFAULT is the
1038 # class's `_default_empty_value` ("" / b"").
1039 only_empty_default = False
1040
1041 def __init__(
1042 self,
1043 *,
1044 default: Any = NOT_PROVIDED,
1045 required: bool = True,
1046 allow_null: bool = False,
1047 validators: Sequence[Callable[..., Any]] = (),
1048 ):
1049 if default is not NOT_PROVIDED:
1050 if callable(default):
1051 raise TypeError(
1052 f"{type(self).__name__}(default=...) must be a static literal. "
1053 f"For empty collections pass default={{}} or default=[]; for "
1054 f"per-row generation use a DB-side expression "
1055 f"(create_now=True, generate=True, RandomStringField)."
1056 )
1057 if isinstance(default, str) and "\\" in default:
1058 # psycopg quotes backslash-bearing strings with `E'...'` escape
1059 # syntax, but pg_get_expr returns the stored DEFAULT as a standard
1060 # `'...'` literal — the two forms don't compare lexically, so
1061 # convergence would flag spurious drift on every sync. Reject at
1062 # declaration time rather than ship a sync that never converges.
1063 raise ValueError(
1064 f"{type(self).__name__}(default=...) must not contain a backslash."
1065 )
1066 if self.only_empty_default:
1067 empty = self._default_empty_value
1068 if default is None:
1069 if not allow_null or required:
1070 raise ValueError(
1071 f"{type(self).__name__} with default=None must also "
1072 f"set allow_null=True and required=False — the "
1073 f"column must accept NULL, and required=True would "
1074 f"reject the defaulted None on every save."
1075 )
1076 # `type()` (not isinstance/==) so bytearray()/memoryview(b"")
1077 # can't slip through — they compare equal to b"" but don't
1078 # deepcopy or serialize like it.
1079 elif type(default) is not type(empty) or default != empty:
1080 raise ValueError(
1081 f"{type(self).__name__} only supports default={empty!r} — "
1082 f"the empty value, used to backfill existing rows when "
1083 f"the field is added to a populated table."
1084 )
1085 elif required:
1086 raise ValueError(
1087 f"{type(self).__name__} with default={empty!r} must also "
1088 f"set required=False — the default fills the field with "
1089 f"an empty value that required=True then rejects."
1090 )
1091 self.default = default
1092 super().__init__(
1093 required=required,
1094 allow_null=allow_null,
1095 validators=validators,
1096 )
1097
1098 def has_default(self) -> bool:
1099 return self.default is not NOT_PROVIDED
1100
1101 def has_persistent_literal_default(self) -> bool:
1102 # `None` would emit `DEFAULT NULL` which is a no-op we don't want to
1103 # track as drift.
1104 return self.has_default() and self.default is not None
1105
1106 def get_default(self) -> Any:
1107 if not self.has_default():
1108 return super().get_default()
1109 # Deep-copy so mutable literals (default=[] / default={}) don't leak
1110 # shared state across instances.
1111 return copy.deepcopy(self.default)
1112
1113 def deconstruct(self) -> tuple[str, str, list[Any], dict[str, Any]]:
1114 name, path, args, kwargs = super().deconstruct()
1115 if self.default is not NOT_PROVIDED:
1116 kwargs["default"] = self.default
1117 return name, path, args, kwargs
1118
1119
1120class ChoicesField[T](DefaultableField[T]):
1121 """Base for fields that accept a ``choices=`` parameter."""
1122
1123 non_migration_attrs = (*DefaultableField.non_migration_attrs, "choices")
1124
1125 # An iterable of (value, display) tuples — possibly nested for optgroups —
1126 # or None. Stored loosely typed because the framework accepts enums,
1127 # lazy iterables, and other shapes that are normalized at init time.
1128 choices: Any
1129
1130 def __init__(
1131 self,
1132 *,
1133 choices: Any = None,
1134 required: bool = True,
1135 allow_null: bool = False,
1136 default: Any = NOT_PROVIDED,
1137 validators: Sequence[Callable[..., Any]] = (),
1138 ):
1139 if isinstance(choices, ChoicesMeta):
1140 choices = choices.choices
1141 elif isinstance(choices, enum.EnumMeta):
1142 choices = [(member.value, member.name) for member in choices]
1143 if isinstance(choices, collections.abc.Iterator):
1144 choices = list(choices)
1145 self.choices = choices
1146 super().__init__(
1147 required=required,
1148 allow_null=allow_null,
1149 default=default,
1150 validators=validators,
1151 )
1152
1153 def preflight(self, **kwargs: Any) -> list[PreflightResult]:
1154 return [*super().preflight(**kwargs), *self._check_choices()]
1155
1156 @classmethod
1157 def _choices_is_value(cls, value: Any) -> bool:
1158 return isinstance(value, str | Promise) or not is_iterable(value)
1159
1160 def _max_length_for_choices_check(self) -> int | None:
1161 return None
1162
1163 def _check_choices(self) -> list[PreflightResult]:
1164 if not self.choices:
1165 return []
1166
1167 if not is_iterable(self.choices) or isinstance(self.choices, str):
1168 return [
1169 PreflightResult(
1170 fix="'choices' must be an iterable (e.g., a list or tuple).",
1171 obj=self,
1172 id="fields.choices_not_iterable",
1173 )
1174 ]
1175
1176 max_length = self._max_length_for_choices_check()
1177 choice_max_length = 0
1178 # Expect [group_name, [value, display]]
1179 for choices_group in self.choices:
1180 try:
1181 group_name, group_choices = choices_group
1182 except TypeError, ValueError:
1183 # Containing non-pairs
1184 break
1185 try:
1186 if not all(
1187 self._choices_is_value(value) and self._choices_is_value(human_name)
1188 for value, human_name in group_choices
1189 ):
1190 break
1191 if max_length is not None and group_choices:
1192 choice_max_length = max(
1193 [
1194 choice_max_length,
1195 *(
1196 len(value)
1197 for value, _ in group_choices
1198 if isinstance(value, str)
1199 ),
1200 ]
1201 )
1202 except TypeError, ValueError:
1203 # No groups, choices in the form [value, display]
1204 value, human_name = group_name, group_choices
1205 if not self._choices_is_value(value) or not self._choices_is_value(
1206 human_name
1207 ):
1208 break
1209 if max_length is not None and isinstance(value, str):
1210 choice_max_length = max(choice_max_length, len(value))
1211
1212 # Special case: choices=['ab']
1213 if isinstance(choices_group, str):
1214 break
1215 else:
1216 if max_length is not None and choice_max_length > max_length:
1217 return [
1218 PreflightResult(
1219 fix="'max_length' is too small to fit the longest value " # noqa: UP031
1220 "in 'choices' (%d characters)." % choice_max_length,
1221 obj=self,
1222 id="fields.max_length_too_small_for_choices",
1223 ),
1224 ]
1225 return []
1226
1227 return [
1228 PreflightResult(
1229 fix="'choices' must be an iterable containing "
1230 "(actual value, human readable name) tuples.",
1231 obj=self,
1232 id="fields.choices_invalid_format",
1233 )
1234 ]
1235
1236 def validate(self, value: Any, model_instance: Model) -> None:
1237 if self.choices is not None and value not in self.empty_values:
1238 for option_key, option_value in self.choices:
1239 if isinstance(option_value, list | tuple):
1240 # This is an optgroup, so look inside the group for
1241 # options.
1242 for optgroup_key, optgroup_value in option_value:
1243 if value == optgroup_key:
1244 return
1245 elif value == option_key:
1246 return
1247 raise exceptions.ValidationError(
1248 "Value %(value)r is not a valid choice.",
1249 code="invalid_choice",
1250 params={"value": value},
1251 )
1252 super().validate(value, model_instance)
1253
1254 def deconstruct(self) -> tuple[str, str, list[Any], dict[str, Any]]:
1255 name, path, args, kwargs = super().deconstruct()
1256 if self.choices is not None:
1257 choices = self.choices
1258 if isinstance(choices, collections.abc.Iterable):
1259 choices = list(choices)
1260 kwargs["choices"] = choices
1261 return name, path, args, kwargs
1262
1263 def get_choices(
1264 self,
1265 include_blank: bool = True,
1266 blank_choice: list[tuple[str, str]] = BLANK_CHOICE_DASH,
1267 ) -> list[tuple[Any, str]]:
1268 """Return choices with an optional blank choice included."""
1269 choices = list(self.choices) if self.choices is not None else []
1270 if include_blank:
1271 blank_defined = any(choice in ("", None) for choice, _ in self.flatchoices)
1272 if not blank_defined:
1273 choices = blank_choice + choices
1274 return choices
1275
1276 @cached_property
1277 def flatchoices(self) -> list[tuple[Any, Any]]:
1278 """Flattened version of choices tuple (choices are fixed at init)."""
1279 if self.choices is None:
1280 return []
1281 flat = []
1282 for choice, value in self.choices:
1283 if isinstance(value, list | tuple):
1284 flat.extend(value)
1285 else:
1286 flat.append((choice, value))
1287 return flat