我正在尝试过滤包含对象列表的JSON对象中包含来自OuterRef的键值对的模型对象。
我有一个模型EntityObject,其字段为“类型”和“数据”。
它在没有子查询的情况下有效:
EntityObject.objects.filter(
type='child',
data__list_of_dicts__contains=[{'some_key': 'value'}]
)
它也可以在不带有__contains的子查询中使用(但需要注释JSONField中的值)。例如,我可以计算data.some_other_key等于父实体的data.some_key的实体:
(EntityObject.objects
.filter(type='parent')
.annotate(data_some_key=Cast(
KeyTextTransform('some_key', 'data'), models.CharField())
)
.annotate(cnt=Subquery(
EntityObject.objects
.filter(type='child')
.annotate(data_some_other_key=Cast(
KeyTextTransform('some_other_key', 'data'), models.CharField())
)
.filter(data_some_other_key=OuterRef('data_some_key')
.values('type')
.order_by()
.annotate(cnt=Count('*'))
.values('cnt')[:1],
output_field=models.IntegerField()
))
现在,这就是我要做的事情:
(EntityObject.objects
.filter(type='parent')
.annotate(data_some_key=Cast(
KeyTextTransform('some_key', 'data'), models.CharField())
)
.annotate(data_some_other_key=Cast(
KeyTextTransform('some_other_key', 'data'), models.CharField())
)
.annotate(cnt=Subquery(
EntityObject.objects
.filter(type='child')
.annotate(data_list_of_dicts=KeyTransform('list_of_dicts', 'data')) # not sure if this is correct
.filter(data_list_of_dicts__contains=[{OuterRef('data_some_key'): OuterRef('data_some_other_key')}]
.values('type')
.order_by()
.annotate(cnt=Count('*'))
.values('cnt')[:1],
output_field=models.IntegerField()
))
但是会引发错误:
TypeError: keys must be a string
即使我从密钥中删除了OuterRef,我也会遇到另一个错误:
(EntityObject.objects
.filter(type='parent')
.annotate(data_some_key=Cast(
KeyTextTransform('some_key', 'data'), models.CharField())
)
.annotate(data_some_other_key=Cast(
KeyTextTransform('some_other_key', 'data'), models.CharField())
)
.annotate(cnt=Subquery(
EntityObject.objects
.filter(type='child')
.annotate(data_list_of_dicts=KeyTransform('list_of_dicts', 'data')) # not sure if this is correct
.filter(data_list_of_dicts__contains=[{'another_key': OuterRef('data_some_other_key')}]
.values('type')
.order_by()
.annotate(cnt=Count('*'))
.values('cnt')[:1],
output_field=models.IntegerField()
))
我遇到另一个错误:
TypeError: OuterRef(data_some_other_key) is not JSON serializable
有什么办法吗?
更新#1
尝试在使用前注释OuterRef:
(EntityObject.objects
.filter(type='parent')
.annotate(data_some_key=Cast(
KeyTextTransform('some_key', 'data'), models.CharField())
)
.annotate(data_some_other_key=Cast(
KeyTextTransform('some_other_key', 'data'), models.CharField())
)
.annotate(cnt=Subquery(
EntityObject.objects
.filter(type='child')
.annotate(data_list_of_dicts=KeyTransform('list_of_dicts', 'data')) # not sure if this is correct
.annotate(parent_some_key=OuterRef('data_some_key')
.annotate(parent_some_other_key=OuterRef('data_some_other_key')
.filter(data_list_of_dicts__contains=[{F('parent_some_key'): F('parent_some_other_key')}]
.values('type')
.order_by()
.annotate(cnt=Count('*'))
.values('cnt')[:1],
output_field=models.IntegerField()
))
现在我得到一个错误:
AttributeError: 'ResolvedOuterRef' object has no attribute 'contains_aggregate'
与https://code.djangoproject.com/ticket/28621相关
更新#2
试图通过简单的动态值进行过滤。与OuterRef具有相同的错误:
(EntityObject.objects
.filter(data_list_of_dicts__contains=[{F('field1'): F('field2')}])
)
投掷:
TypeError: keys must be a string
仅动态值:
(EntityObject.objects
.filter(data_list_of_dicts__contains=[{'some_key': F('field')}])
)
投掷:
TypeError: F(id) is not JSON serializable
创建了另一个问题