summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorJeremy Nauta <jeremypnauta@gmail.com>2023-07-06 20:36:48 -0600
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2023-09-07 06:19:08 +0200
commitf333e3513e8bdf5ffeb6eeb63021c230082e6f95 (patch)
tree45840089369287128724be0a63e3af36f3178469 /docs
parentcafe7266ee69f7e017ddbc0d440084ace559b04b (diff)
Fixed #31300 -- Added GeneratedField model field.
Thanks Adam Johnson and Paolo Melchiorre for reviews. Co-Authored-By: Lily Foote <code@lilyf.org> Co-Authored-By: Mariusz Felisiak <felisiak.mariusz@gmail.com>
Diffstat (limited to 'docs')
-rw-r--r--docs/ref/checks.txt5
-rw-r--r--docs/ref/models/fields.txt65
-rw-r--r--docs/releases/5.0.txt7
3 files changed, 77 insertions, 0 deletions
diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt
index b8789ecf6f..72699ac136 100644
--- a/docs/ref/checks.txt
+++ b/docs/ref/checks.txt
@@ -208,6 +208,11 @@ Model fields
* **fields.E180**: ``<database>`` does not support ``JSONField``\s.
* **fields.E190**: ``<database>`` does not support a database collation on
``<field_type>``\s.
+* **fields.E220**: ``<database>`` does not support ``GeneratedField``\s.
+* **fields.E221**: ``<database>`` does not support non-persisted
+ ``GeneratedField``\s.
+* **fields.E222**: ``<database>`` does not support persisted
+ ``GeneratedField``\s.
* **fields.E900**: ``IPAddressField`` has been removed except for support in
historical migrations.
* **fields.W900**: ``IPAddressField`` has been deprecated. Support for it
diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt
index fbc90e5420..a41eb7b1d2 100644
--- a/docs/ref/models/fields.txt
+++ b/docs/ref/models/fields.txt
@@ -1215,6 +1215,71 @@ when :attr:`~django.forms.Field.localize` is ``False`` or
information on the difference between the two, see Python's documentation
for the :mod:`decimal` module.
+``GeneratedField``
+------------------
+
+.. versionadded:: 5.0
+
+.. class:: GeneratedField(expression, db_persist=None, output_field=None, **kwargs)
+
+A field that is always computed based on other fields in the model. This field
+is managed and updated by the database itself. Uses the ``GENERATED ALWAYS``
+SQL syntax.
+
+There are two kinds of generated columns: stored and virtual. A stored
+generated column is computed when it is written (inserted or updated) and
+occupies storage as if it were a regular column. A virtual generated column
+occupies no storage and is computed when it is read. Thus, a virtual generated
+column is similar to a view and a stored generated column is similar to a
+materialized view.
+
+.. attribute:: GeneratedField.expression
+
+ An :class:`Expression` used by the database to automatically set the field
+ value each time the model is changed.
+
+ The expressions should be deterministic and only reference fields within
+ the model (in the same database table). Generated fields cannot reference
+ other generated fields. Database backends can impose further restrictions.
+
+.. attribute:: GeneratedField.db_persist
+
+ Determines if the database column should occupy storage as if it were a
+ real column. If ``False``, the column acts as a virtual column and does
+ not occupy database storage space.
+
+ PostgreSQL only supports persisted columns. Oracle only supports virtual
+ columns.
+
+.. attribute:: GeneratedField.output_field
+
+ An optional model field instance to define the field's data type. This can
+ be used to customize attributes like the field's collation. By default, the
+ output field is derived from ``expression``.
+
+.. admonition:: Refresh the data
+
+ Since the database always computed the value, the object must be reloaded
+ to access the new value after :meth:`~Model.save()`, for example, by using
+ :meth:`~Model.refresh_from_db()`.
+
+.. admonition:: Database limitations
+
+ There are many database-specific restrictions on generated fields that
+ Django doesn't validate and the database may raise an error e.g. PostgreSQL
+ requires functions and operators referenced in a generated columns to be
+ marked as ``IMMUTABLE`` .
+
+ You should always check that ``expression`` is supported on your database.
+ Check out `MariaDB`_, `MySQL`_, `Oracle`_, `PostgreSQL`_, or `SQLite`_
+ docs.
+
+.. _MariaDB: https://mariadb.com/kb/en/generated-columns/#expression-support
+.. _MySQL: https://dev.mysql.com/doc/refman/en/create-table-generated-columns.html
+.. _Oracle: https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-TABLE.html#GUID-F9CE0CC3-13AE-4744-A43C-EAC7A71AAAB6__BABIIGBD
+.. _PostgreSQL: https://www.postgresql.org/docs/current/ddl-generated-columns.html
+.. _SQLite: https://www.sqlite.org/gencol.html#limitations
+
``GenericIPAddressField``
-------------------------
diff --git a/docs/releases/5.0.txt b/docs/releases/5.0.txt
index 5b8abc8498..b9a871c8e9 100644
--- a/docs/releases/5.0.txt
+++ b/docs/releases/5.0.txt
@@ -129,6 +129,13 @@ sets a database-computed default value. For example::
created = models.DateTimeField(db_default=Now())
circumference = models.FloatField(db_default=2 * Pi())
+Database generated model field
+------------------------------
+
+The new :class:`~django.db.models.GeneratedField` allows creation of database
+generated columns. This field can be used on all supported database backends
+to create a field that is always computed from other fields.
+
More options for declaring field choices
----------------------------------------