mirror of
https://github.com/django/django.git
synced 2025-01-05 07:55:47 +00:00
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>
This commit is contained in:
parent
bd3b1dfa24
commit
65f3cfce59
@ -1628,80 +1628,25 @@ Django also defines a set of fields that represent relations.
|
|||||||
.. class:: ForeignKey(to, on_delete, **options)
|
.. class:: ForeignKey(to, on_delete, **options)
|
||||||
|
|
||||||
A many-to-one relationship. Requires two positional arguments: the class to
|
A many-to-one relationship. Requires two positional arguments: the class to
|
||||||
which the model is related and the :attr:`~ForeignKey.on_delete` option.
|
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
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
class Car(models.Model):
|
|
||||||
manufacturer = models.ForeignKey(
|
|
||||||
"Manufacturer",
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
)
|
|
||||||
# ...
|
|
||||||
|
|
||||||
|
|
||||||
class Manufacturer(models.Model):
|
class Manufacturer(models.Model):
|
||||||
# ...
|
name = models.TextField()
|
||||||
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``
|
|
||||||
|
|
||||||
from django.db import models
|
|
||||||
from products.models import AbstractCar
|
|
||||||
|
|
||||||
|
|
||||||
class Manufacturer(models.Model):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Car(AbstractCar):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# 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):
|
class Car(models.Model):
|
||||||
manufacturer = models.ForeignKey(
|
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
|
||||||
"production.Manufacturer",
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
)
|
|
||||||
|
|
||||||
This sort of reference, called a lazy relationship, can be useful when
|
The first positional argument can be either a concrete model class or a
|
||||||
resolving circular import dependencies between two applications.
|
: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
|
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
|
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
|
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``
|
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
|
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
|
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 database column name (unless you write custom SQL). You'll always
|
||||||
deal with the field names of your model object.
|
deal with the field names of your model object.
|
||||||
|
|
||||||
.. _foreign-key-arguments:
|
.. _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
|
See :doc:`One-to-one relationships </topics/db/examples/one_to_one>` for usage
|
||||||
examples of ``OneToOneField``.
|
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
|
Field API reference
|
||||||
===================
|
===================
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user