【发布时间】:2019-07-16 02:24:23
【问题描述】:
这是一个非常具体的问题。
我的模型有一个名为“内容”的 JSON,在该 JSON 中有一个名为“名称”的键。我的目标是将名称放入查询集的新列中,但这似乎很难做到,因为 content__name 在某些情况下不存在,如果您只是使用额外选择它,它会抛出例外。
queryset = queryset.extra(select={'_content_name': "SELECT content->>'name'"})
最终结果需要包含包含名称和不包含名称的内容,不包含名称的可以替换为“-”等字符或完全为空。 最终结果必须是查询集,而不是 RawQueryset。
我尝试过但效果不佳的事情:
- 之前使用过滤,尝试与原来的差异联合,由于查询集的列数量不同或列的类型不同,无法联合。您不能将作为 JSON 的
content__name与作为字符串的content->>'name'合并到同一列中。
qs = queryset.filter(~Q(content__name__iexact='')).values_list('content__name')
qs2 = queryset.difference(qs).extra(select={'_item_name': "SELECT content->>'name'"}).values_list('_item_name')
queryset = qs.union(qs2)
在这种情况下,它也可以说 _item_name 不是 values_list 上的有效列,即使在使用 extra 创建它之后也是如此。
尝试使用 F 表达式,但不太奏效,因为查询集在比较 JSON 时会有点混乱:
queryset.annotate(_item_name=F('content__name'))尝试使用 RawSQL,但它不适用于我正在使用的场景(Django 管理员)。
总结一下,我需要以下其中一项才能正常工作:
- 联合两个具有不同值/值类型的查询集的方法
- 即使内容是 JSON 也可以注释 F 的方法
- 或者一种将 RawQuerysets 转换为普通查询集而不丢失额外列的方法。
【问题讨论】:
标签: python json django django-admin django-queryset