Skip to content

Commit

Permalink
Merge pull request #122 from Plebbimon/chore/m2m-through-docs
Browse files Browse the repository at this point in the history
Chore/m2m through docs
  • Loading branch information
tOgg1 authored Feb 27, 2024
2 parents 52837c0 + 52fbb6b commit cf9ed2f
Showing 1 changed file with 56 additions and 0 deletions.
56 changes: 56 additions & 0 deletions docs/guide/nested-fields.rst
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,62 @@ populator of the relationship.
If you don't have an existing type for creating a user, e.g. the "CreateCatInput" we used above,
you can set the type to "auto", which will create a new type.

Many to many with `through` models
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The way Django handles a `through` model internally is functionally similar to using many to one relationships. This
implies that the more convienient option is to use `many_to_one_extras` instead of `many_to_many_extras` when dealing
with `through` models.

If you have a many to many relationship with a `through` model, you can use
a `many_to_one_extras` field to specify how to handle the `through` model.
Due to how the m2m fields are automatically generated using the input schema, it is recommended to use the
`many_to_one_extras` field instead of the `many_to_many_extras` field.

Suppose we have a `Dog` model with a many to many relationship
with a `Cat` model, but we want to keep track of the number of times a dog
has fought a cat. We can do this with a `through` model:

.. code:: python
class Dog(models.Model):
owner = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
name = models.TextField()
fights = models.ManyToManyField(Cat, through='Fight')
class Fight(models.Model):
dog = models.ForeignKey(Dog, on_delete=models.CASCADE, related_name='fights')
cat = models.ForeignKey(Cat, on_delete=models.CASCADE, related_name='fights')
times = models.IntegerField(default=0)
We can then create a mutation to create a dog, and add a fight to it:

.. code:: python
class CreateDogMutation(DjangoCreateMutation):
class Meta:
model = Dog
many_to_one_extras = {
'fights': {
'exact': {"type": "auto"}
}
}
This will infer the dog's ID, and allows us to create a fight in the same
mutation:

.. code::
mutation {
createDog(input: {
name: "Buster",
fights: [{cat: "Q2F0Tm9kZTox", times: 1}]
}}){
dog{
...DogInfo
}
}
}
One to one extras
~~~~~~~~~~~~~~~~~

Expand Down

0 comments on commit cf9ed2f

Please sign in to comment.