Django 异步嵌套模型加载

问题描述 投票:0回答:1

我有模型:

class ObjectA(models.Model):
    alias = models.CharField(max_length=50)
    objectb = models.ForeignKey(ObjectB, on_delete=models.PROTECT)

    class Meta:
        db_table = "objecta"

class ObjectB(models.Model):
    name = models.CharField(max_length=50)
    objectc = models.ForeignKey(ObjectC, on_delete=models.PROTECT)

    class Meta:
        db_table = "objectb"

class ObjectC(models.Model):
    name = models.CharField(max_length=50)

    class Meta:
        db_table = "objectc"

在我的 ViewSet 函数中,我想获取 ObjectA,然后从引用的 ObjectC 获取名称。 在同步 django 中我会做

get_object_or_404(ObjectA, alias="My alias").objectb.objectc.name
但这在异步 Django 中引发了一个错误:

django.core.exceptions.SynchronousOnlyOperation:您不能从异步上下文中调用它 - 使用线程或sync_to_async。

我找到了一个对我来说看起来不太干净的解决方案:

from django.db.models.query import aprefetch_related_objects
from django.shortcuts import get_object_or_404

get_objecta_model = sync_to_async(get_object_or_404, thread_sensitive=True)
objecta = await get_objecta_model(ObjectA, name=alias)

await aprefetch_related_objects([objecta], "objectb__objectc")

objecta.objectb.objectc.name
python django asynchronous django-rest-framework
1个回答
0
投票

据我所知,这是您当前可以使用的解决方法之一。异步模式不支持延迟查找。

另一种方法是使用显式

.aget
.select_related
而不是使用
get_object_or_404
帮助器:

try:
    objecta = await ObjectA.objects.select_related("objectb__objectc").aget(name="foo")
    objectc_name = objecta.objectb.objectc.name
except ObjectA.DoesNotFound:
    return HttpResponseNotFound()
© www.soinside.com 2019 - 2024. All rights reserved.