Bladeren bron

Fixed #26322 -- Consolidated lazy relationships details in docs/ref/models/fields.txt.

Reorganized docs to list and explain the types of lazy relationships
that can be defined in related fields.

Co-authored-by: Natalia <124304+nessita@users.noreply.github.com>
Clifford Gama 5 maanden geleden
bovenliggende
commit
65f3cfce59
1 gewijzigde bestanden met toevoegingen van 127 en 68 verwijderingen
  1. 127 68
      docs/ref/models/fields.txt

+ 127 - 68
docs/ref/models/fields.txt

@@ -1628,80 +1628,25 @@ Django also defines a set of fields that represent relations.
 .. class:: ForeignKey(to, on_delete, **options)
 
 A many-to-one relationship. Requires two positional arguments: the class to
-which the model is related and the :attr:`~ForeignKey.on_delete` option.
-
-.. _recursive-relationships:
-
-To create a recursive relationship -- an object that has a many-to-one
-relationship with itself -- use ``models.ForeignKey('self',
-on_delete=models.CASCADE)``.
-
-.. _lazy-relationships:
-
-If you need to create a relationship on a model that has not yet been defined,
-you can use the name of the model, rather than the model object itself::
-
-    from django.db import models
-
-
-    class Car(models.Model):
-        manufacturer = models.ForeignKey(
-            "Manufacturer",
-            on_delete=models.CASCADE,
-        )
-        # ...
-
-
-    class Manufacturer(models.Model):
-        # ...
-        pass
-
-Relationships defined this way on :ref:`abstract models
-<abstract-base-classes>` are resolved when the model is subclassed as a
-concrete model and are not relative to the abstract model's ``app_label``:
-
-.. code-block:: python
-    :caption: ``products/models.py``
-
-    from django.db import models
-
-
-    class AbstractCar(models.Model):
-        manufacturer = models.ForeignKey("Manufacturer", on_delete=models.CASCADE)
-
-        class Meta:
-            abstract = True
-
-.. code-block:: python
-    :caption: ``production/models.py``
+which the model is related and the :attr:`~ForeignKey.on_delete` option::
 
     from django.db import models
-    from products.models import AbstractCar
 
 
     class Manufacturer(models.Model):
-        pass
-
-
-    class Car(AbstractCar):
-        pass
-
+        name = models.TextField()
 
-    # Car.manufacturer will point to `production.Manufacturer` here.
-
-To refer to models defined in another application, you can explicitly specify
-a model with the full application label. For example, if the ``Manufacturer``
-model above is defined in another application called ``production``, you'd
-need to use::
 
     class Car(models.Model):
-        manufacturer = models.ForeignKey(
-            "production.Manufacturer",
-            on_delete=models.CASCADE,
-        )
+        manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
 
-This sort of reference, called a lazy relationship, can be useful when
-resolving circular import dependencies between two applications.
+The first positional argument can be either a concrete model class or a
+:ref:`lazy reference <lazy-relationships>` to a model class.
+:ref:`Recursive relationships <recursive-relationships>`, where a model has a
+relationship with itself, are also supported.
+
+See :attr:`ForeignKey.on_delete` for details on the second positional
+argument.
 
 A database index is automatically created on the ``ForeignKey``. You can
 disable this by setting :attr:`~Field.db_index` to ``False``.  You may want to
@@ -1714,9 +1659,9 @@ Database Representation
 
 Behind the scenes, Django appends ``"_id"`` to the field name to create its
 database column name. In the above example, the database table for the ``Car``
-model will have a ``manufacturer_id`` column. (You can change this explicitly by
-specifying :attr:`~Field.db_column`) However, your code should never have to
-deal with the database column name, unless you write custom SQL. You'll always
+model will have a ``manufacturer_id`` column. You can change this explicitly by
+specifying :attr:`~Field.db_column`, however, your code should never have to
+deal with the database column name (unless you write custom SQL). You'll always
 deal with the field names of your model object.
 
 .. _foreign-key-arguments:
@@ -2266,6 +2211,120 @@ accepted by :class:`ForeignKey`, plus one extra argument:
 See :doc:`One-to-one relationships </topics/db/examples/one_to_one>` for usage
 examples of ``OneToOneField``.
 
+.. _lazy-relationships:
+
+Lazy relationships
+------------------
+
+Lazy relationships allow referencing models by their names (as strings) or
+creating recursive relationships. Strings can be used as the first argument in
+any relationship field to reference models lazily. A lazy reference can be
+either :ref:`recursive <recursive-relationships>`,
+:ref:`relative <relative-relationships>` or
+:ref:`absolute <absolute-relationships>`.
+
+.. _recursive-relationships:
+
+Recursive
+~~~~~~~~~
+
+To define a relationship where a model references itself, use ``"self"`` as the
+first argument of the relationship field::
+
+    from django.db import models
+
+
+    class Manufacturer(models.Model):
+        name = models.TextField()
+        suppliers = models.ManyToManyField("self", symmetrical=False)
+
+
+When used in an :ref:`abstract model <abstract-base-classes>`, the recursive
+relationship resolves such that each concrete subclass references itself.
+
+.. _relative-relationships:
+
+Relative
+~~~~~~~~
+
+When a relationship needs to be created with a model that has not been defined
+yet, it can be referenced by its name rather than the model object itself::
+
+    from django.db import models
+
+
+    class Car(models.Model):
+        manufacturer = models.ForeignKey(
+            "Manufacturer",
+            on_delete=models.CASCADE,
+        )
+
+
+    class Manufacturer(models.Model):
+        name = models.TextField()
+        suppliers = models.ManyToManyField("self", symmetrical=False)
+
+Relationships defined this way on :ref:`abstract models
+<abstract-base-classes>` are resolved when the model is subclassed as a
+concrete model and are not relative to the abstract model's ``app_label``:
+
+.. code-block:: python
+    :caption: ``products/models.py``
+
+    from django.db import models
+
+
+    class AbstractCar(models.Model):
+        manufacturer = models.ForeignKey("Manufacturer", on_delete=models.CASCADE)
+
+        class Meta:
+            abstract = True
+
+.. code-block:: python
+    :caption: ``production/models.py``
+
+    from django.db import models
+    from products.models import AbstractCar
+
+
+    class Manufacturer(models.Model):
+        name = models.TextField()
+
+
+    class Car(AbstractCar):
+        pass
+
+In this example, the ``Car.manufacturer`` relationship will resolve to
+``production.Manufacturer``, as it points to the concrete model defined
+within the ``production/models.py`` file.
+
+.. admonition:: Reusable models with relative references
+
+    Relative references allow the creation of reusable abstract models with
+    relationships that can resolve to different implementations of the
+    referenced models in various subclasses across different applications.
+
+.. _absolute-relationships:
+
+Absolute
+~~~~~~~~
+
+Absolute references specify a model using its ``app_label`` and class name,
+allowing for model references across different applications. This type of lazy
+relationship can also help resolve circular imports.
+
+For example, if the ``Manufacturer`` model is defined in another application
+called ``thirdpartyapp``, it can be referenced as::
+
+    class Car(models.Model):
+        manufacturer = models.ForeignKey(
+            "thirdpartyapp``.Manufacturer",
+            on_delete=models.CASCADE,
+        )
+
+Absolute references always point to the same model, even when used in an
+:ref:`abstract model <abstract-base-classes>`.
+
 Field API reference
 ===================