丰富Django QuerySet的不同结果

时间:2019-02-13 11:46:39

标签: python django django-queryset

目标

查询所有产品,将它们切片,然后返回包含添加的key:value的那些产品的子集,换句话说,就是丰富了。

有效但无法使用的代码

我无法使用此代码,因为我使用了分页器,分页器访问count中的QuerySet。如果我通过了切片的QuerySet ,则该计数仅用于切片的部分,而不是整个QuerySet,因此为什么我不能使用它。

products_qs = final_qs[paginator.get_offset(request):
                       paginator.get_offset(request) + paginator.get_limit(request)]
for product in products_qs:
    product.raw['super_cool_new_key'] = ms_response.get('results').get(product.id)

这很好用,当我打印数据时,我可以看到super_cool_new_key在每种产品中都富集。太棒了问题?好吧,我不得不将其切成薄片,现在 count 方法不再适用。当然,我可以做类似的事情:

products_qs.count = final_qs.count

继续我的生活,但是感觉……很老套,也许不是?

代码,我希望它能正常工作,但不能

for i in range(paginator.get_offset(request),
               paginator.get_offset(request) + paginator.get_limit(request)):
    product = final_qs[i]
    product.raw['super_cool_new_key'] = ms_response.get('results').get(product.id)

当我看到数据输出时,super_cool_new_key不存在。为什么我无法确定自己的想法?

也许我今天过得很忙,我不理解通过引用进行访问,所以我删除了Middlemonkey。

final_qs = final_qs.all()
for i in range(paginator.get_offset(request),
               paginator.get_offset(request) + paginator.get_limit(request)):
    final_qs[i].raw['super_cool_new_key'] = ms_response.get('results').get(final_qs[i].id, '')

怀疑

很明显,关于代码差异的原因是一种方法起作用而另一种方法不起作用的罪魁祸首。我的钱在下面:

  • 切片
  • 迭代

查看Django Docs for QuerySet

  

迭代。 QuerySet是可迭代的,并且在您第一次对其进行迭代时会执行其数据库查询。

然后进行切片:

  

切片。如限制查询集所述,可以使用Python的数组切片语法对QuerySet进行切片。切片未评估的QuerySet通常会返回另一个未评估的QuerySet,但是如果您使用slice语法的“ step”参数,则Django将执行数据库查询,并会返回列表

那么我就不能切片了,因为我不使用“ step”参数来切片。由于它返回了一个未评估的QuerySet ,因此我想使用的代码在理论上应该可以使用。 (不是总是这样吗?哈哈)

好,这样可以清除以下事实:在第一个编码选项中,我进行了for x in x_container的迭代,而执行了QuerySet。这可能是答案吗?所以我修改了代码:

剧透警报:仍然无效

final_qs = final_qs.all()
for i in range(paginator.get_offset(request),
               paginator.get_offset(request) + paginator.get_limit(request)):
    product = final_qs[i]
    product.raw['super_cool_new_key'] = ms_response.get('results').get(product.id)

嗯...有帮助吗?

一个建议的答案,扰流板警报不起作用

from django.db.models import When, Case, Value, CharField
when = [ When(id=k, then=Value(v)) for k,v in ms_response.get('results').items()]
p = final_qs[paginator.get_offset(request)
             :paginator.get_offset(request) + paginator.get_limit(request)]
p = p.annotate(super_cool_new_key=Case(
            *when,
            default=Value(''),
            output_field=CharField()
        )
    )

我也尝试了不使用 slice 的情况,但是使用了.all().annotate()。还是没用。它不起作用,不是由于发生异常,而是因为当我看到输出时,super_cool_new_key不存在,这意味着它并没有丰富对象,这就是重点。

1 个答案:

答案 0 :(得分:0)

听起来您正在寻找的答案类似于使用hereWhen的答案Case。您可以使用以下内容:

from django.db.models import When, Case, Value, CharField

ms_response = {5458: 'abc', 9900: 'def'}
whens = [
    When(id=k, then=Value(v)) for k, v in ms_response.items()
]
qs = YourModelName.objects.all().annotate(
    super_cool_key=Case(
        *whens,
        default=Value('xyz'),
        output_field=CharField()
    )
)

当您致电qs.get(id=5458).super_cool_key时,它将返回'abc'