结合Django F,Value和dict注释查询集 [英] Combining Django F, Value and a dict to annotate a queryset
问题描述
我有一种情况,我想用字典中的外部准备数据注释查询集。我想执行以下操作:
I have a scenario where I want to annotate a queryset with externally prepared data in a dict. I want to do something like the following:
value_dict = {"model1": 123.4, "model2": 567.8}
qs = ModelClass.objects.annotate(
value=Value(value_dict.get(F('model__code'), 0))
)
当前结果显示为0,因为F()似乎不是查找字典的最佳方法,因为它不返回a
The results currently show all as 0 as the F() doesn't seem to be the best way to look up the dict seeing as it doesn't return a string and it is resolved further down the track.
我们将不胜感激您的帮助和建议
Your help and suggestions would be much appreciated
m当前在Python 3.6和Django 1.11上
I'm currently on Python 3.6 and Django 1.11
推荐答案
我到目前为止最接近的是遍历字典并结合一个整个基于dict键的过滤查询集。
像这样:
The closest I've come so far is to loop through the dict and union a whole bunch of filtered query sets based on the dict keys. Like so:
value_dict = {"model1": 123.4, "model2": 567.8}
array_of_qs = []
for k, v in value_dict.items():
array_of_qs.append(
ModelClass.objects.filter(model__code=k).annotate(value=Value(v))
)
qs = array_of_qs[0].union(*array_of_qs[1:])
然后,qs将得到我想要的结果,该结果是基于注释到每个实例的字典键的字典值。
The qs will then have the result that I want, which is the values of the dict based on the keys of the dict annotated to each instance.
这样做的好处是,只有当我决定使用qs时,才会对数据库进行一次调用,除了整个过程不会影响我所理解的DB。
The beauty of this is that there is only one call to the db which is when I decide to use qs, other than that this whole process doesn't touch the DB from what I understand.
不确定是否有更好的方法,但是在接受此方法之前将等待查看是否还有其他响应。
Not sure there is a better way yet but will wait to see if there are other responses before accepting this one.
新的改进的工作方法以下
不幸的是,上述内容不适用于values_list或当前版本为1.11的Django的值由于此问题:
https://code.djangoproject.com/ticket/28900
Unfortunately the above doesn't work with values_list or values as of this current version 1.11 of Django due to this issue: https://code.djangoproject.com/ticket/28900
我在下面设计了一种更简洁的方法:
I devised a cleaner way below:
value_dict = {"model1": 123.4, "model2": 567.8}
whens = [
When(model__code=k, then=v) for k, v in value_dict.items()
]
qs = ModelClass.objects.all().annotate(
value=Case(
*whens,
default=0,
output_field=DecimalField()
)
)
希望对别人有帮助
这篇关于结合Django F,Value和dict注释查询集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!