如何在 Django-Graphene 中进行多对多突变?

发布于 2025-01-09 04:07:38 字数 2270 浏览 0 评论 0原文

我正在 Django 3.2 和 graphene-django 2.15 中工作。 顺便说一下,我还在学习如何使用石墨烯。

注意:我不允许共享所有代码,因此我出于此问题的目的重写了它。如果您发现任何与问题无关的错误,请通知我。

我有一个团队模型,它与默认的 Django 组模型具有多对多关系:

from django.db import models
from django.contrib.auth.models import Group

class Team(models.Model):
    team_id = models.IntegerField(unique=True)  # Custom ID not related to Django's pk
    name = models.CharField(max_length=255)
    groups = models.ManyToManyField(Group, blank=True)

这是我的架构:

import graphene
from django.contrib.auth.models import Group
from graphene_django import DjangoObjectType

from .models import Team


class TeamType(DjangoObjectType):
    class Meta:
        model = Team

class GroupType(DjangoObjectType):
    class Meta:
        model = Group


class GroupInput(graphene.InputObjectType):
    id = graphene.ID(required=True)


class UpdateTeam(graphene.Mutation):
    team = graphene.Field(TeamType)

    class Arguments:
        team_id = graphene.ID(required=True)
        name = graphene.String(required=True)
        groups_id = graphene.List(GroupInput, required=True)

    def mutate(self, info, team_id, name, groups_id):
        team = Team.objects.get(pk=team_id)

        team.name = name
        team.groups = Group.objects.filter(pk__in=groups_id)

        team.save()
        return UpdateTeam(team=team)

        
class TeamMutations(graphene.ObjectType):
    update_team = UpdateTeam.Field()

class Mutation(TeamMutations, graphene.ObjectType):
    pass

schema = graphene.schema(query=Query, mutation=Mutation)

当我执行此查询时:

mutation{
  updateTeam(
    teamId: 65961826547,
    name: "My Team Name",
    groupsId: [{id: 1}, {id: 2}]
  ) {
    team {
      team_id,
      name,
      groups {
        name,
      }
    }
  }
}

我收到此错误:

{
  "errors": [
    {
      "message": "Field 'id' expected a number but got {'id': '1'}.",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "updateTeam"
      ]
    }
  ],
  "data": {
    "updateTeam": null
  }
}

我不太明白多对多关系由石墨烯管理。 有人能为我提供解决方案和一些解释吗?多谢。

I'm working in Django 3.2 and graphene-django 2.15.
I'm still learning how to use Graphene by the way.

Note: I'm not allowed to share all the code so I rewrote it for the purpose of this question. Please notify me if you've found any error unrelated to the question.

I have an Team model which has a Many-to-Many relationship with the default Django Group model:

from django.db import models
from django.contrib.auth.models import Group

class Team(models.Model):
    team_id = models.IntegerField(unique=True)  # Custom ID not related to Django's pk
    name = models.CharField(max_length=255)
    groups = models.ManyToManyField(Group, blank=True)

Here is my schema:

import graphene
from django.contrib.auth.models import Group
from graphene_django import DjangoObjectType

from .models import Team


class TeamType(DjangoObjectType):
    class Meta:
        model = Team

class GroupType(DjangoObjectType):
    class Meta:
        model = Group


class GroupInput(graphene.InputObjectType):
    id = graphene.ID(required=True)


class UpdateTeam(graphene.Mutation):
    team = graphene.Field(TeamType)

    class Arguments:
        team_id = graphene.ID(required=True)
        name = graphene.String(required=True)
        groups_id = graphene.List(GroupInput, required=True)

    def mutate(self, info, team_id, name, groups_id):
        team = Team.objects.get(pk=team_id)

        team.name = name
        team.groups = Group.objects.filter(pk__in=groups_id)

        team.save()
        return UpdateTeam(team=team)

        
class TeamMutations(graphene.ObjectType):
    update_team = UpdateTeam.Field()

class Mutation(TeamMutations, graphene.ObjectType):
    pass

schema = graphene.schema(query=Query, mutation=Mutation)

When I perform this query:

mutation{
  updateTeam(
    teamId: 65961826547,
    name: "My Team Name",
    groupsId: [{id: 1}, {id: 2}]
  ) {
    team {
      team_id,
      name,
      groups {
        name,
      }
    }
  }
}

I get this error:

{
  "errors": [
    {
      "message": "Field 'id' expected a number but got {'id': '1'}.",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "updateTeam"
      ]
    }
  ],
  "data": {
    "updateTeam": null
  }
}

I don't really understand how Many-to-may relationships are managed by Graphene.
Does someone has a solution and some explanations for me? Thanks a lot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

时光沙漏 2025-01-16 04:07:38

我找到了解决方案。

一开始我以为是和石墨烯有关的东西,特别是这些InputObjectTypes,没猜对。

但问题其实很简单。

GroupInput 需要一个值,它是一个 ID。

class GroupInput(graphene.InputObjectType):
    id = graphene.ID(required=True)

因为我把它放在 graphene.List() 中,所以我现在需要一个 ID 列表:

class UpdateTeam(graphene.Mutation):
    ...

    class Arguments:
        ...
        groups_id = graphene.List(GroupInput, required=True)

但是在我的 API 调用中,我没有给出实际列表,而是给出了一个字典:

mutation{
  updateTeam(
    ...
    groupsId: [{id: 1}, {id: 2}]
  ) {
    ...
  }

所以这有效:

mutation{
  updateTeam(
    ...
    groupsId: [1, 2]
  ) {
    ...
  }

注 1:

graphene.ID 也接受以字符串形式给出的 id:

    groupsId: ["1", "2"]

注 2:

我实际上删除了 GroupInput 并直接放入 graphene.ID 字段在石墨烯.List

class UpdateTeam(graphene.Mutation):
    ...

    class Arguments:
        ...
        groups_id = graphene.List(graphene.ID, required=True)

I found the solution.

At first, I thought there was something related to graphene, especially these InputObjectTypes, I didn't get correctly.

But the issue is actually very simple.

The GroupInput is expecting a single value, which it an ID.

class GroupInput(graphene.InputObjectType):
    id = graphene.ID(required=True)

Because I put it in graphene.List(), I'm now expecting a list of ID's:

class UpdateTeam(graphene.Mutation):
    ...

    class Arguments:
        ...
        groups_id = graphene.List(GroupInput, required=True)

But in my API call, instead of giving an actual list, I gave a dict:

mutation{
  updateTeam(
    ...
    groupsId: [{id: 1}, {id: 2}]
  ) {
    ...
  }

So this works:

mutation{
  updateTeam(
    ...
    groupsId: [1, 2]
  ) {
    ...
  }

Note 1:

graphene.ID also accepts ids given as strings:

    groupsId: ["1", "2"]

Note 2:

I actually removed my GroupInput and put the graphene.ID field directly in the graphene.List:

class UpdateTeam(graphene.Mutation):
    ...

    class Arguments:
        ...
        groups_id = graphene.List(graphene.ID, required=True)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文