mirror of
https://github.com/django/django.git
synced 2025-01-03 06: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)
|
||||
|
||||
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::
|
||||
which the model is related and the :attr:`~ForeignKey.on_delete` option::
|
||||
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Car(models.Model):
|
||||
manufacturer = models.ForeignKey(
|
||||
"Manufacturer",
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
# ...
|
||||
|
||||
|
||||
class Manufacturer(models.Model):
|
||||
# ...
|
||||
pass
|
||||
name = models.TextField()
|
||||
|
||||
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):
|
||||
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
|
||||
===================
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user