英文:
django orm: use annotate case on prefetch result
问题
这是我的模型的近似副本:
class To(models.Model):
pass
class FromA(models.Model):
to = models.ForeignKey(To)
class FromB(models.Model):
to = models.ForeignKey(To)
是否有办法编写这样的查询?
To.objects.annotate(from=Case(
When(froma__isnull=False, then=Prefetch("froma")),
When(fromb__isnull=False, then=Prefetch("fromb"))
))
请注意,我已经为你翻译了代码部分,并删除了额外的内容。如果你需要更多帮助,请随时提出。
英文:
this is a near replica of my models:
class To(models.Model):
pass
class FromA(models.Model):
to = models.ForeignKey(To)
class FromB(models.Model):
to = models.ForeignKey(To)
is there a way to write a query like this?
To.objects.annotate(from=Case(
When(froma__isnull=False, then=Prefetch("froma")),
When(fromb__isnull=False, then=Prefetch("fromb"))
))
答案1
得分: 0
到目前为止,这是我找到的最佳答案。
from django.db.models import Subquery, OuterRef
froma_info = FromA.objects.filter(To=OuterRef('pk')).values('carrot', 'pear', 'apple')[:1]
fromb_info = FromB.objects.filter(To=OuterRef('pk')).values('carrot', 'pear', 'apple')[:1]
to_list = To.objects.annotate(
from=Case(
When(froma__isnull=False, then=Subquery(froma_info)),
When(fromb__isnull=False, then=Subquery(fromb_info)),
default=Value({
'carrot': '无可用来源',
'pear': '',
'apple': '',
}),
output_field=JSONField(),
)
)
这是您提供的代码的翻译部分。
英文:
so far, this is the best answer I have found.
from django.db.models import Subquery, OuterRef
froma_info = FromA.objects.filter(To=OuterRef('pk')).values('carrot', 'pear', 'apple')[:1]
fromb_info = FromB.objects.filter(To=OuterRef('pk')).values('carrot', 'pear', 'apple')[:1]
to_list = To.objects.annotate(
from=Case(
When(froma__isnull=False, then=Subquery(froma_info)),
When(fromb__isnull=False, then=Subquery(fromb_info)),
default=Value({
'carrot': 'No from available',
'pear': '',
'apple': '',
}),
output_field=JSONField(),
)
)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论