2017-05-10 14 views
0

我已經採取了從Django的文檔下面的例子中,除了代替數字的按鍵增加了一個關鍵的「99」:查詢JSONField對於只有

>>> Dog.objects.create(name='Rufus', data={ 
... 'breed': 'labrador', 
...  'owner': { 
...   'name': 'Bob', 
...   'other_pets': [{ 
...    'name': 'Fishy', 
...   }], 
...  }, 
... }) 
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', '99': 'FINDME',}) 

>>> Dog.objects.filter(data__breed='collie') 
<QuerySet [<Dog: Meg>]> 

我想下面也返回「梅格」狗:

Dog.objects.filter(data__99='FINDME') 

但是,似乎因爲我的鍵是一個整數,Django不能正確處理這個問題。我如何在python jsonfields中使用整數鍵是字符串?

回答

0

它看起來並不是一個很好的選擇。下面是來自Django的/的contrib/Postgres的/場/ jsonb.py一個片段:

def as_sql(self, compiler, connection): 
    key_transforms = [self.key_name] 
    previous = self.lhs 
    while isinstance(previous, KeyTransform): 
     key_transforms.insert(0, previous.key_name) 
     previous = previous.lhs 
    lhs, params = compiler.compile(previous) 
    if len(key_transforms) > 1: 
     return "{} #> %s".format(lhs), [key_transforms] + params 
    try: 
     int(self.key_name) 
    except ValueError: 
     lookup = "'%s'" % self.key_name 
    else: 
     lookup = "%s" % self.key_name 
    return "%s -> %s" % (lhs, lookup), params 

由此看來,它看起來像它試圖把每一個鍵轉換成整數,並使用它(如果可能)的關鍵。

這裏是一個黑客,你可以做,以使該查詢的方式,你希望它:

def jsonb_integer_keys_to_str(qs, key): 
    return qs.model.objects.raw(qs.query.__str__().replace('-> {}'.format(key), "-> '{}'".format(key))) 

而且使用它作爲這樣的:

jsonb_integer_keys_to_str(Dog.objects.filter(data__99='FINDME'), 99) 

該解決方案是過於具體,而是將工作在這種情況下。它所做的是修改postgres sql並將引號放在正確的位置。

+0

你爲什麼不把鍵存儲爲整數?而不是'99':'FINDME'使用'99:'FINDME',即'data = {'breed':'collie',99:'FINDME',}' –

+1

好問題!原來django把所有的json鍵變成了字符串:(我不知道爲什麼。) – theicfire

+1

哦,我知道爲什麼 - 因爲JSON不允許整數鍵 – theicfire