Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Deep nested objects in django won't work due to async

未关闭
#84 6 条评论 3 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
35/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
停滞
技术栈
django, graphql, python
领域
api, backend, database

调研方向

先从 issue 中的 Subscription、TaskType 和 TaskResultType resolver 示例开始,然后使用 Django 设置复现嵌套的 task → result → profiles subscription。跟踪 async-context 错误发生的位置,并验证完整的嵌套 subscription 能够返回 profile 数据,而无需额外的 resolver 变通方案。

由索引模型根据 Issue 内容生成。

描述

  • GraphQL AioWS version: (not using AioWS, only django-channels)
  • Python version: 3.8.2
  • Operating System: MacOSX
Description

I am trying to get clients to subscribe to my graphql with a nested object in django. The request looks like this:

subscription {
  taskUpdated(id:"04a5e92bc9084ad981481ab4314a1d33", updateInterval: 3) {
    id
    token
    result {
      id,
      profiles {
        id
      }
    }
  } 
}

Tasks contain one result which contain multiple profiles.

What I Did

In my subscription class I used the sync_to_async method which works if used for the first level:

class Subscription(graphene.ObjectType):
    task_updated = graphene.Field(
        TaskType, id=graphene.String(), update_interval=graphene.Int()
    )

    async def resolve_task_updated(root, info, id, update_interval):
        print("TRYING TO RESOLVE")
        while True:
            print("While true")
            task = await sync_to_async(Task.objects.get, thread_sensitive=True)(
                pk=id
            )
            yield task
            await asyncio.sleep(update_interval)

Using the query only targeting task.id everything works perfectly. Once I try to target task.result (which is a new object). I receive the error:

You cannot call this from an async context - use a thread or sync_to_async.

I managed to get a workaround by updating the TaskType and updating the resolver for the result like so:

class TaskType(DjangoObjectType):
    class Meta:
        model = TaskModel
        fields = "__all__"

    result = graphene.Field(TaskResultType)

    async def resolve_result(self, info):
        return await sync_to_async(
            TaskResult.objects.get, thread_sensitive=True
        )(task=self.id)

That way I could get to the next level (task -> result). When I try to subscribe to task -> result -> profiles there is no way to receive the data anymore. The same error from above is thrown. Even if I update the ResultType accordingly to fetch all profiles async:

class TaskResultType(DjangoObjectType):
    class Meta:
        model = TaskResult
        fields = "__all__"

    profiles = graphene.List(ProfileType)

    async def resolve_profiles(self, info):
        return await sync_to_async(
            Profile.objects.filter, thread_sensitive=True
        )(task_result=self.id)

I thought dynamic querying of objects and subscribing to nested objects would be an out of the box functionality but it is really difficult. I can't be the only person using this repo to actually receive ORM data?

主要语言
Python
星标
270
派生
85
PR 合并指标
30 天内没有已合并 PR

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

graphql-python/graphql-ws 的其他 Issue

查看 graphql-python/graphql-ws 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。