Python Graphene 处理多对多关系

标签 python django graphql graphene-python graphene-django

如果这个问题在其他地方得到回答,那么我很抱歉,但是下类后两天,仍然没有雪茄......

我有一个播放器模型:

class Player(models.Model):
    name = models.CharField(max_length=60)
    discord_id = models.CharField(max_length=60, null=True)
    known_npcs = models.ManyToManyField(NPC)

玩家可以认识很多NPC,而任何NPC都可以被很多玩家认识。

NPC 没什么特别的:

class NPC(models.Model):
    image = models.ImageField()
    name = models.CharField(max_length=50)
    description = models.TextField()

谜题的最后一部分是事实,事实是附加到 NPC 的一些信息,但是一个人可以认识一个 NPC,但玩家不一定知道所有与 NPC 相关的事实,因此事实是看起来像这样:

class Fact(models.Model):
    fact = models.TextField()
    known_by = models.ManyToManyField(Player)
    npc = models.ForeignKey(NPC, on_delete=models.DO_NOTHING, null=True)

现在在 Graphite 烯中,我想创建一个 Player 和 allPlayers 查询,它会给我这个:

{
  allPlayers {
    name
    knownNPCs {
      image
      name
      description
      factsKnown {
        fact
      }
    }
  }
}

已知的事实只是基于 Fact 对象中的多对多关系的事实。

到目前为止,我创建的内容会返回数据,但不会根据玩家父级过滤事实,只是显示与 npc 相关的所有事实:(

事实架构

class FactType(DjangoObjectType):
    class Meta:
        model = Fact
        filter_fields = ["id"]

class Query(object):
    fact = Node.Field(FactType)
    all_Facts = graphene.List(FactType)

    def resolve_all_Facts(self, info, **kwargs):
        return Fact.objects.all()

NPC架构

class NPCType(DjangoObjectType):
    class Meta:
        model = NPCS

class Query(object):
    all_NPCs = graphene.Field(NPCType)
    facts = graphene.List(FactType)
    def resolve_all_NPCs(self, info, **kwargs):
        return NPCS.objects.all()

玩家架构:

class PlayerType(DjangoObjectType):
    class Meta:
        model = Player
        interfaces = (Node,)
        filter_fields = ["id"]


class Query(object):
    player = Node.Field(PlayerType)
    all_players = graphene.List(PlayerType)

    def resolve_all_players(self, info, **kwargs):
        return Player.objects.all()

    def resolve_player(self, info, **kwargs):
        player = Player.objects.filter(id=info.id)

最佳答案

对于任何仍在阅读的人,我设法通过创建“filteredFacts”字段来解决这个问题:

class PlayerType(DjangoObjectType):
class Meta:
    model = Player
    filter_fields = ["id"]

filtered_facts = graphene.List(FactGroup)

def resolve_filtered_facts(self, info, **kwargs):
    groups = defaultdict(list)
    facts = self.known_facts.all()
    for fact in facts:
        groups[fact.npc].append(fact.fact)
    grouped_facts = []
    for key, value in groups.items():
        grouped_facts.append(FactGroup(npc=key, facts=value))

    return grouped_facts

这会获取玩家已知的所有事实并按 NPC 对其进行分组,与另一方的结果相同...

关于Python Graphene 处理多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58718721/

相关文章:

python - 在Python中的if语句上重新加载主脚本

python - Django 模板不显示表数据

graphql - 对 Gatsby 中的多个查询对 GraphQL 查询进行排序

laravel - Lighthouse GraphQL 将 ID 转换为字符串而不是整数?

python - 属性错误 : module 'pandas' has no attribute 'Dataframe' with rapsberry Pi

python - 如何使用ElementTree按属性值查找xml元素

python - 比较两个图像(包含建筑物)的相似性的最有效方法是什么

python - 如何使用 IIS 6 + FastCGI + Django 设置启用 SSL?

django - Docker&Celery - 错误 : Pidfile (celerybeat. pid) 已经存在

reactjs - 什么是 Apollo 中的片段匹配器