【问题标题】:Combining Django F, Value and a dict to annotate a queryset结合 Django F、Value 和 dict 来注释查询集
【发布时间】:2018-06-19 14:03:16
【问题描述】:

我有一个场景,我想用字典中的外部准备数据注释查询集。我想做如下的事情:

value_dict = {"model1": 123.4, "model2": 567.8}
qs = ModelClass.objects.annotate(
    value=Value(value_dict.get(F('model__code'), 0))
)

结果当前显示为 0,因为 F() 似乎不是查找 dict 的最佳方法,因为它不返回字符串,并且在跟踪中进一步解析。

非常感谢您的帮助和建议

我目前使用的是 Python 3.6 和 Django 1.11

【问题讨论】:

    标签: python django


    【解决方案1】:

    到目前为止,我最接近的是遍历 dict 并根据 dict 键合并一大堆过滤的查询集。 像这样:

    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 将得到我想要的结果,它是基于注释到每个实例的 dict 的键的 dict 的值。

    这样做的好处在于,当我决定使用 qs 时,只有一次调用 db,除此之外,据我了解,整个过程不会触及数据库。

    尚不确定是否有更好的方法,但在接受此方法之前会等待是否有其他响应。

    以下新改进的工作方法

    不幸的是,由于这个问题,上述 Django 的当前版本 1.11 中的 values_list 或 values 不起作用: https://code.djangoproject.com/ticket/28900

    我在下面设计了一种更清洁的方法:

    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()
        )
    )
    

    希望对某人有所帮助

    【讨论】:

    • whens 是一个列表,您不能使用**whens,因为它不是字典而是列表。
    • 你是正确的@user4426017,它是一个列表,但是我没有用**whens 扩展它,我用*whens 扩展它,这是预期的
    • 基于@Omar 所做的,如果您的字典包含变量作为键值,请使用then=Value(v)。为我工作。
    猜你喜欢
    • 1970-01-01
    • 2020-07-04
    • 2011-01-25
    • 2022-01-10
    • 2023-03-29
    • 2020-06-13
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    相关资源
    最近更新 更多