Nested Mutations¶
This package provides support for deeply nested mutations through a field extension and some wrapper input classes.
It makes sense for the inputs to be different when updating an object vs creating one. So we provide different input wrappers for each type of operation. It also makes sense that the api provided would be different depending on the type of relationship between the related models.
Wrappers for nested objects for create mutations¶
One to One¶
CRUDOneToOneCreateInput can be used when you want to create or assign a related object, alongside the creation of your root object. The resulting schema will provide two actions for your mutation create and assign which are mutually exclusive. create is of type UserCreateInput which you will need to provide and assign is of type ID. A brief example follows.
Now we can create or assign nested objects on either side of the relationship.
Or we could create the goat through the creation of the user.
We could ofcourse use the assign action to assign an existing goat to a user or vice versa by providing the ID.
Note
There is no limit to how deeply nested the mutations can be. If the goat had a second relationship to another model say Collar and Collar had a relationship back to the User model through a designer field we could create or assign the nested objects in one go.
One to Many¶
CRUDOneToManyCreateInput. Similarly to the one to one wrapper it provides two actions create and assign which are mutually exclusive. The only difference is that the relationship is through a ForeignKey meaning the other side of the relationship would be Many to One requiring a different wrapper. Here's a brief example:
pk 72 in one go. Many to One¶
CRUDManyToOneCreateInput. This wrapper is used when the relationship is Many to One. It provides two actions create and assign which are NOT mutually exclusive. The inputs are of course lists and of type SomeModelInput and ID respectively. Here's a brief example:
Many to Many¶
CRUDManyToManyCreateInput is provided for Many-to-Many relationships. It provides two actions create and assign which are NOT mutually exclusive. The inputs are ofcourse lists again but there's one important difference. They are internally wrapped again to provide a mechanism for the user to provide through_defaults for the relationship either on assignment or creation. The type for through_defaults is JSON and the values should follow snake case.
Note
Please note that the inputs for the nested objects need not be the same as the inputs for the creation of the objects. In fact you have the flexibility to define different inputs for the nested objects limiting which fields are exposed through each nested mutation.
Wrappers for nested objects for update mutations¶
These wrappers expect two inputs to be provided instead of the one that was necessary for creation. The first is for creation of new related objects when updating the current object and the second is for updates to the data of already related objects.
One to One¶
CRUDOneToOneUpdateInput can be used when alongside an update mutation you want to update related objects. The resulting schema will provide three possible actions for your mutation and a boolean flag.
createof typeUserInputused to create a new related object.assignof typeIDused to assign an existing objects as related.Note that you can use
nullto remove the relationship if the field is nullable.updateof typeUserPartialused to update the fields of an existing related object.deleteof typeboolindicating whether the related object should be deleted.Note that this flag can be used together with assign or create to delete the previously related object.
The respective update input of the example used for the One to One creation mutation above would read:
Note
Currently when using @strawberry_django.partial all fields are marked as optional when auto is used. However, the ID is required for performing nested updates. For consistency and to avoid any errors you should always use id: ID when defining partials for update mutations when it is the root object. The id can be omitted when the partial is used as a nested input and if defined it won't be used in any way to update the related object.
One to Many¶
CRUDOneToManyUpdateInput can be used when alongside an update mutation you want to update related objects. The resulting schema will provide three possible actions for your mutation and a boolean flag. These are the same as the ones provided by the One to One wrapper, and they function in exactly the same fashion.
Many to One¶
CRUDManyToOneUpdateInput can be used when alongside an update mutation you want to update related objects. The resulting schema will provide four possible actions for your mutation. These are as follows:
createof typeList[UserInput]used to create new related objects.assignof typeList[ID]used to assign relations with existing objects.updateof typeList[UserPartial]used to update the fields of existing related objects.removeof typeList[CRUDRemoveInput]which wraps anIDand aboolflag indicating whether the removed object should be deleted.
Note
Please note that the UserPartial used in the example above unlike the case with One to Many and One to One has a requirement for the id field. Please take care to ensure the id is declared as mandatory when declaring your input class.
Many to Many¶
CRUDManyToManyUpdateInput can be used when alongside an update mutation you want to update related objects. The resulting schema will provide four possible actions for your mutation. These are as follows:
createof typeList[CRUDManyToManyItem]which wraps two inputs.objectDataof typeUserInputused for the fields of the related object.throughDefaultsof typeJSONused for any data stored in thethroughmodel if one exists.
assignof typeList[CRUDManyToManyID]which wraps two inputs.idof typeIDused to assign relations with existing objects.throughDefaultsof typeJSONused for any data stored in thethroughmodel if one exists.
updateof typeList[CRUDManyToManyItemUpdate]which wraps two inputs.objectDataof typeUserPartialused to update the fields of the related object.throughDefaultsof typeJSONused to update the fields of thethroughmodel if one exists.
removeof typeList[CRUDRemoveInput]which wraps anIDand aboolflag indicating whether the removed object should be deleted.
Note
Please note that again the UserPartial input must declare an id field of type ID and not auto.