【问题标题】:Issue joining data in graphene-django with a ManyToMany field使用 ManyToMany 字段在 graphene-django 中加入数据
【发布时间】:2021-07-24 00:59:11
【问题描述】:

我一直在尝试找到一个很好的示例来返回一个包含跨多对多字段连接数据的查询集,但我没有找到。

给定以下模型:

class Task(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    task_assignee = models.ForeignKey("User")
    is_draft = models.Boolean(default=True)
    detail = models.ManyToManyField("Detail", through="TaskDetails")


class Detail(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    detail_name = models.CharField(max_length=250)

class TaskDetails(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    task = models.ForeignKey("Task", related_name="detail_tasks")
    detail = models.ForeignKey("Detail", related_name="task_details")
    detail_value = models.CharField(max_length=250)

我想返回 Task 的数据及其相关详细信息。根据this question 上的答案,我将架构调整为以下内容:

class TaskDetailsType(DjangoObjectType):

    class Meta:
        model = TaskDetails
        fields = ("id", "detail_name", "detail_value")

        detail_name = graphene.String()

    def resolve_detail_name(value_obj, info):
        return value_obj.detail.detail_name


class TaskType(DjangoObjectType):

    class Meta:
        model = Task
        fields = ("id", "task_details")

    task_details = graphene.List(TaskDetailsType)

    def resolve_task_details(value_obj, info):
        return value_obj.detail_tasks

我正在运行的查询:

Task.objects.filter(task_assignee_id=info.context.user.id) \
    .filter(is_draft=False)

当我运行它时,我得到一个错误:

{'errors': [{'message': '用户错误:预期可迭代,但没有为字段 TaskType.taskDetails 找到一个。'}, {'message': '用户错误:预期可迭代,但没有为字段 TaskType.taskDetails.'} 找到一个,{'message':'用户错误:预期可迭代,但没有为字段 TaskType.taskDetails.'}] 找到一个,'data':{'getInboxTasks':[{' id':'a430e49d-c9c3-4839-8f2c-aaebbfe9ef3a','taskDetails':无},{'id':'74c8dacc-1bfd-437a-ae34-7e111075ac5e','taskDetails':无},{'id' :'10956caa-d74f-4a01-a5cf-9cac6a15c5a3','taskDetails':无}]}}

【问题讨论】:

  • 您是否尝试通过 .all() 传递查询集而不是管理器实例?
  • 我将使用正在运行的查询更新我的问题。我不确定。

标签: django graphene-python graphene-django


【解决方案1】:

正如@schillingt 指出并由石墨烯暗示的那样,问题在于RelatedManager 是不可迭代的:

def resolve_task_details(value_obj, info):
    return value_obj.detail_tasks  # related manager

所以改变很简单:

def resolve_task_details(value_obj, info):
    return value_obj.detail_tasks.all()  # queryset -> iterable

【讨论】:

  • 我没有意识到我可以在对象的解析器中做到这一点。还有很多东西要学:) 非常感谢@schillingt 和 Melvyn
  • 解析器函数相当于 Django Rest Framework 中的序列化器。它负责将 WhatYourTypeIs 转换为 ObjectType。使用 DjangoObjectType,您可以免费获得一些东西,例如从 Django 模型实例到 Graphene ObjectType 的转换。这就是为什么您可以返回“TaskDetail 实例的查询集”并最终得到一个 JSON 对象的 JSON 列表,其中包含 id、detailName 和 detailValue 键客户端。
猜你喜欢
  • 2016-01-11
  • 2015-08-13
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 2012-02-04
  • 2014-02-04
  • 1970-01-01
相关资源
最近更新 更多