mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
Refs #34140 -- Applied rst code-block to non-Python examples.
Thanks to J.V. Zammit, Paolo Melchiorre, and Mariusz Felisiak for reviews.
This commit is contained in:
committed by
Mariusz Felisiak
parent
7bb741d787
commit
534ac48297
@@ -2,8 +2,6 @@
|
||||
Many-to-many relationships
|
||||
==========================
|
||||
|
||||
.. highlight:: pycon
|
||||
|
||||
To define a many-to-many relationship, use
|
||||
:class:`~django.db.models.ManyToManyField`.
|
||||
|
||||
@@ -36,7 +34,9 @@ objects, and a ``Publication`` has multiple ``Article`` objects:
|
||||
What follows are examples of operations that can be performed using the Python
|
||||
API facilities.
|
||||
|
||||
Create a few ``Publications``::
|
||||
Create a few ``Publications``:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> p1 = Publication(title='The Python Journal')
|
||||
>>> p1.save()
|
||||
@@ -45,11 +45,15 @@ Create a few ``Publications``::
|
||||
>>> p3 = Publication(title='Science Weekly')
|
||||
>>> p3.save()
|
||||
|
||||
Create an ``Article``::
|
||||
Create an ``Article``:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> a1 = Article(headline='Django lets you build web apps easily')
|
||||
|
||||
You can't associate it with a ``Publication`` until it's been saved::
|
||||
You can't associate it with a ``Publication`` until it's been saved:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> a1.publications.add(p1)
|
||||
Traceback (most recent call last):
|
||||
@@ -57,26 +61,35 @@ You can't associate it with a ``Publication`` until it's been saved::
|
||||
ValueError: "<Article: Django lets you build web apps easily>" needs to have a value for field "id" before this many-to-many relationship can be used.
|
||||
|
||||
Save it!
|
||||
::
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> a1.save()
|
||||
|
||||
Associate the ``Article`` with a ``Publication``::
|
||||
Associate the ``Article`` with a ``Publication``:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> a1.publications.add(p1)
|
||||
|
||||
Create another ``Article``, and set it to appear in the ``Publications``::
|
||||
Create another ``Article``, and set it to appear in the ``Publications``:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> a2 = Article(headline='NASA uses Python')
|
||||
>>> a2.save()
|
||||
>>> a2.publications.add(p1, p2)
|
||||
>>> a2.publications.add(p3)
|
||||
|
||||
Adding a second time is OK, it will not duplicate the relation::
|
||||
Adding a second time is OK, it will not duplicate the relation:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> a2.publications.add(p3)
|
||||
|
||||
Adding an object of the wrong type raises :exc:`TypeError`::
|
||||
Adding an object of the wrong type raises :exc:`TypeError`:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> a2.publications.add(a1)
|
||||
Traceback (most recent call last):
|
||||
@@ -84,18 +97,24 @@ Adding an object of the wrong type raises :exc:`TypeError`::
|
||||
TypeError: 'Publication' instance expected
|
||||
|
||||
Create and add a ``Publication`` to an ``Article`` in one step using
|
||||
:meth:`~django.db.models.fields.related.RelatedManager.create`::
|
||||
:meth:`~django.db.models.fields.related.RelatedManager.create`:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> new_publication = a2.publications.create(title='Highlights for Children')
|
||||
|
||||
``Article`` objects have access to their related ``Publication`` objects::
|
||||
``Article`` objects have access to their related ``Publication`` objects:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> a1.publications.all()
|
||||
<QuerySet [<Publication: The Python Journal>]>
|
||||
>>> a2.publications.all()
|
||||
<QuerySet [<Publication: Highlights for Children>, <Publication: Science News>, <Publication: Science Weekly>, <Publication: The Python Journal>]>
|
||||
|
||||
``Publication`` objects have access to their related ``Article`` objects::
|
||||
``Publication`` objects have access to their related ``Article`` objects:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> p2.article_set.all()
|
||||
<QuerySet [<Article: NASA uses Python>]>
|
||||
@@ -105,7 +124,9 @@ Create and add a ``Publication`` to an ``Article`` in one step using
|
||||
<QuerySet [<Article: NASA uses Python>]>
|
||||
|
||||
Many-to-many relationships can be queried using :ref:`lookups across
|
||||
relationships <lookups-that-span-relationships>`::
|
||||
relationships <lookups-that-span-relationships>`:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> Article.objects.filter(publications__id=1)
|
||||
<QuerySet [<Article: Django lets you build web apps easily>, <Article: NASA uses Python>]>
|
||||
@@ -123,7 +144,9 @@ relationships <lookups-that-span-relationships>`::
|
||||
<QuerySet [<Article: NASA uses Python>]>
|
||||
|
||||
The :meth:`~django.db.models.query.QuerySet.count` function respects
|
||||
:meth:`~django.db.models.query.QuerySet.distinct` as well::
|
||||
:meth:`~django.db.models.query.QuerySet.distinct` as well:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> Article.objects.filter(publications__title__startswith="Science").count()
|
||||
2
|
||||
@@ -137,7 +160,9 @@ The :meth:`~django.db.models.query.QuerySet.count` function respects
|
||||
<QuerySet [<Article: Django lets you build web apps easily>, <Article: NASA uses Python>]>
|
||||
|
||||
Reverse m2m queries are supported (i.e., starting at the table that doesn't have
|
||||
a :class:`~django.db.models.ManyToManyField`)::
|
||||
a :class:`~django.db.models.ManyToManyField`):
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> Publication.objects.filter(id=1)
|
||||
<QuerySet [<Publication: The Python Journal>]>
|
||||
@@ -162,12 +187,16 @@ a :class:`~django.db.models.ManyToManyField`)::
|
||||
<QuerySet [<Publication: Highlights for Children>, <Publication: Science News>, <Publication: Science Weekly>, <Publication: The Python Journal>]>
|
||||
|
||||
Excluding a related item works as you would expect, too (although the SQL
|
||||
involved is a little complex)::
|
||||
involved is a little complex):
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> Article.objects.exclude(publications=p2)
|
||||
<QuerySet [<Article: Django lets you build web apps easily>]>
|
||||
|
||||
If we delete a ``Publication``, its ``Articles`` won't be able to access it::
|
||||
If we delete a ``Publication``, its ``Articles`` won't be able to access it:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> p1.delete()
|
||||
>>> Publication.objects.all()
|
||||
@@ -176,7 +205,9 @@ If we delete a ``Publication``, its ``Articles`` won't be able to access it::
|
||||
>>> a1.publications.all()
|
||||
<QuerySet []>
|
||||
|
||||
If we delete an ``Article``, its ``Publications`` won't be able to access it::
|
||||
If we delete an ``Article``, its ``Publications`` won't be able to access it:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> a2.delete()
|
||||
>>> Article.objects.all()
|
||||
@@ -184,7 +215,9 @@ If we delete an ``Article``, its ``Publications`` won't be able to access it::
|
||||
>>> p2.article_set.all()
|
||||
<QuerySet []>
|
||||
|
||||
Adding via the 'other' end of an m2m::
|
||||
Adding via the 'other' end of an m2m:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> a4 = Article(headline='NASA finds intelligent life on Earth')
|
||||
>>> a4.save()
|
||||
@@ -194,7 +227,9 @@ Adding via the 'other' end of an m2m::
|
||||
>>> a4.publications.all()
|
||||
<QuerySet [<Publication: Science News>]>
|
||||
|
||||
Adding via the other end using keywords::
|
||||
Adding via the other end using keywords:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> new_article = p2.article_set.create(headline='Oxygen-free diet works wonders')
|
||||
>>> p2.article_set.all()
|
||||
@@ -203,7 +238,9 @@ Adding via the other end using keywords::
|
||||
>>> a5.publications.all()
|
||||
<QuerySet [<Publication: Science News>]>
|
||||
|
||||
Removing ``Publication`` from an ``Article``::
|
||||
Removing ``Publication`` from an ``Article``:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> a4.publications.remove(p2)
|
||||
>>> p2.article_set.all()
|
||||
@@ -211,7 +248,9 @@ Removing ``Publication`` from an ``Article``::
|
||||
>>> a4.publications.all()
|
||||
<QuerySet []>
|
||||
|
||||
And from the other end::
|
||||
And from the other end:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> p2.article_set.remove(a5)
|
||||
>>> p2.article_set.all()
|
||||
@@ -219,7 +258,9 @@ And from the other end::
|
||||
>>> a5.publications.all()
|
||||
<QuerySet []>
|
||||
|
||||
Relation sets can be set::
|
||||
Relation sets can be set:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> a4.publications.all()
|
||||
<QuerySet [<Publication: Science News>]>
|
||||
@@ -227,13 +268,17 @@ Relation sets can be set::
|
||||
>>> a4.publications.all()
|
||||
<QuerySet [<Publication: Science Weekly>]>
|
||||
|
||||
Relation sets can be cleared::
|
||||
Relation sets can be cleared:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> p2.article_set.clear()
|
||||
>>> p2.article_set.all()
|
||||
<QuerySet []>
|
||||
|
||||
And you can clear from the other end::
|
||||
And you can clear from the other end:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> p2.article_set.add(a4, a5)
|
||||
>>> p2.article_set.all()
|
||||
@@ -246,7 +291,9 @@ And you can clear from the other end::
|
||||
>>> p2.article_set.all()
|
||||
<QuerySet [<Article: Oxygen-free diet works wonders>]>
|
||||
|
||||
Recreate the ``Article`` and ``Publication`` we have deleted::
|
||||
Recreate the ``Article`` and ``Publication`` we have deleted:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> p1 = Publication(title='The Python Journal')
|
||||
>>> p1.save()
|
||||
@@ -255,7 +302,9 @@ Recreate the ``Article`` and ``Publication`` we have deleted::
|
||||
>>> a2.publications.add(p1, p2, p3)
|
||||
|
||||
Bulk delete some ``Publications`` - references to deleted publications should
|
||||
go::
|
||||
go:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> Publication.objects.filter(title__startswith='Science').delete()
|
||||
>>> Publication.objects.all()
|
||||
@@ -265,7 +314,9 @@ go::
|
||||
>>> a2.publications.all()
|
||||
<QuerySet [<Publication: The Python Journal>]>
|
||||
|
||||
Bulk delete some articles - references to deleted objects should go::
|
||||
Bulk delete some articles - references to deleted objects should go:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> q = Article.objects.filter(headline__startswith='Django')
|
||||
>>> print(q)
|
||||
@@ -274,7 +325,9 @@ Bulk delete some articles - references to deleted objects should go::
|
||||
|
||||
After the :meth:`~django.db.models.query.QuerySet.delete`, the
|
||||
:class:`~django.db.models.query.QuerySet` cache needs to be cleared, and the
|
||||
referenced objects should be gone::
|
||||
referenced objects should be gone:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> print(q)
|
||||
<QuerySet []>
|
||||
|
||||
Reference in New Issue
Block a user