python - 如何使用预取子查询的功能注释 django 查询集
问题描述
我想在查询集上有一个字段,该字段status
派生自一组预取的反馈值的函数。
反馈示例:
feedback = [
{'action': 0, 'user': 1},
{'action': 1, 'user': 13},
]
如果我在序列化器上写这个,我会这样做:
def get_status(self, obj):
# Squash all feedback into single status value
fb = obj.feedback.all()
vals = [f.action for f in fb]
if len(vals) == 0:
return 0 # Unconfirmed
if sum(vals) == 0:
return 1 # Confirmed
return 2 # Rejected
但是,我想将此逻辑向下移动到我的视图的查询集中,以启用字段排序。
queryset = Foo.objects\
.prefetch_related('feedback')\
.annotate(status="???")
我想知道哪组可用的查询表达式可以模仿get_status
上面的 python 函数的逻辑。
解决方案
您不能在 an 中调用函数,.annotate(..)
因为数据库层不知道函数。您可以尝试将上述内容转换为表达式。你不需要那个.prefetch_related(..)
。在这里你可以使用Case
[Django-doc]和When
[Django-doc]:
from django.db.models import Case, Count, IntegerField, Sum, Value, When
queryset = Foo.objects.annotate(
nfeedback=Count('feedback'),
sumfeedback=Sum('feedback__action')
).annotate(
status=Case(
When(nfeedback=0, then=Value(0)),
When(sumfeedback=0, then=Value(1)),
default=Value(2),
output_field=IntegerField()
)
)
推荐阅读
- html - 弹性项目的IE11溢出
- instagram - 我们可以使用 Instagram API 进行本地开发吗
- c# - WPF 交互触发器 IsKeyboardFocusWithinChanged 不会触发
- three.js - three.js 行:17299:4 警告 X4121 - 如何防止这种情况“提高性能”?
- laravel - 允许多个中间件 laravel 的控制器方法访问
- javascript - 是否需要将 PrimeNG pDefer 与延迟加载一起使用?
- django - Django在同一页面上的两个表单
- android - 取消/关闭图标上的通知
- jquery - DataTables 是否支持波斯语?
- apache - apache2 如何拒绝与非托管域的连接