2016-07-25 276 views
3

我想了解一种方法来查询我的模型的特定实例上的postgres JSONField中的数据。查询Django模型的JSONField的内容

从我所看到的情况来看,所有的用例都是相同的,如果你有一个属性JSONField,然后选择你的模型的所有实例,其中属性 - >> color ='red'或其他。

让我们给这个更真实的例子,假设我们有一个模型Shoe,它有价格和数量,无论作为字段,但随后也JSONField称为versions,这是对象的数组,具有每个对象让每个版本都特别的东西。

因此,如果鞋模型的一个实例是飞人乔丹,属性JSONField可能看起来像:

[ 
    { 
     color: black, 
     edition: limited, 
     tongueColor: red 
    }, 
    { 
     color: black, 
     edition: standard 
    }, 
    { 
     color: gold, 
     edition: fancy, 
     bright: very 
    } 
] 

因此,有两件事情可以做,我们可以:

  1. 查询模型对于所有有可用版本的鞋子,其颜色:黑色(将返回我们的Air Jordans,加上其他鞋子)或
  2. 查询JSONField版本内所有对象的模型实例,其中color = black。所以如果我们已经有Shoe.objects.filter(name='Air Jordans')什么的,可以在最后加上一些方法或东西来返回上面的前两个对象color == black

我可以在网上找到第一个例子,但不是第二个例子。

我可以把对象放入内存并从那里过滤,但是这个JSONField是我希望存储大量任意数据的地方,所以能够在不将整个blob存入内存的情况下进行查询是相当重要的。 JSONField可以支持吗?

+0

你怎么知道我们可以做第二件事? – valignatev

+1

我不太确定,但我认为你可以这样做:'.filter(versions__contains = {'color':'black'})'或'.filter(versions__contains = [{'color':'black'}} ])'。否则,你应该创建一些自定义查找并使用'json_to_recordset()'https://www.postgresql.org/docs/9.5/static/functions-json.html#FUNCTIONS-JSON-PROCESSING-TABLE –

+0

@valentjedi - 我有不知道这是否可能,但很可能不是。 – cbrainerd

回答

1

@AntoinePinsard我指出了正确的方向 - json_to_recordset()。

我目前使用的是这样的:

SELECT * FROM (
    SELECT j.* from shoes, json_to_recordset(json_field_name) as 
    j(color text, edition text, tongueColor: text, bright text) where 
    shoes.shoe_name = 'Air Jordan' 
) subset 
WHERE subset.color= "black" 

所以内部的select语句将在内部建立一个记录,看起来像这样:

 
color | edition | tongueColor | bright 
------+----------+-------------+-------- 
black | limited | red   | 
black | standard |    | 
gold | fancy |    | very 

,然后外语句查询该内部记录集(在这种情况下,其中color ='black'并且将返回:

 
color | edition | tongueColor | bright 
------+----------+-------------+-------- 
black | limited | red   | 
black | standard |    | 

感谢大家的帮助!

+0

您是否可以将此解决方案应用到Django ORM中? – skulk001

1

这可能会为你工作:

Shoes.objects.filter(yourJsonFieldName__contains={'colors': 'black'})