In the latest strawberry-django version (0.47.1) single-level nested objects CUD operations work fine, however, multiple level nested objects cannot be created/updated. Consider the following types hierarchy:
class Project(models.Model):
foo = models.CharField(max_length=255)
class Milestone(models.Model):
bar = models.CharField(max_length=255)
project = models.ForeignKey(Project, on_delete=models.PROTECT)
class Issue(models.Model):
baz = models.CharField(max_length=255)
milestone = models.ForeignKey(Milestone, on_delete=models.PROTECT)
When trying to execute the following mutation:
mutation CreateIssue ($input: IssueInput!) {
createIssue (input: $input) {
... on IssueType {
id
milestone {
id
project {
id
name
}
}
}
}
}
input:
"input": {
"foo": "Some Issue",
"milestone": {
"bar": "Some Milestone",
"project": {
"baz": "Some Project",
},
},
}
Error occurs:
ValueError: Cannot assign "UNSET": "Milestone.project" must be a "Project" instance.
That happens because of two issues:
_parse_data
function check for None
pk value but not UNSET
:strawberry-django/strawberry_django/mutations/resolvers.py
Lines 102 to 107 in 9025ee5
So UNSET
added to parsed data. After fixing if-clause and checking for both None
and UNSET
values another issue arises:
model
used to create dummy instance and full-clean oneThe problem is in the same function:
strawberry-django/strawberry_django/mutations/resolvers.py
Lines 102 to 103 in 9025ee5
parent model (Milestone
but not Project
) is used, so even if full clean passes somehow (in unit tests that's the case as all models have name
field), finally incorrect instance would be created. The fix seems to be quite straightforward also:
related_model = get_model_fields(model).get(k).related_model
v = create(info, related_model, v.data or {})
Using parent model we can extract related model and pass one to create
function.
mutation UpdateProject ($input: ProjectInputPartial!) {
updateProject (input: $input) {
... on ProjectType {
id
milestones {
id
issues {
id
}
}
}
}
}
Input:
"input": {
"id": to_base64("ProjectType", project.pk),
"milestones": [{
"name": "Milestone 1",
"issues": [{
"name": "Some Issue",
}]
}]
}
Error:
django.core.exceptions.FieldError: Cannot resolve keyword 'issues' into field. Choices are:
That happens because nested issues are passed directly to Django create
(or get_or_create
):
strawberry-django/strawberry_django/mutations/resolvers.py
Lines 623 to 627 in 9025ee5
This issue seems to be related to #383 and #449 PR. #360 is also related as update_m2m
function is to be updated.
I'm working on the PR to address the issues mentioned above, creating this issue to further refer one from the PR.
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too