9

की JSONField सूची फ़िल्टर मैं नए JSONField साथ Django 1.9 चलाने के लिए और अगले टेस्ट मॉडल है:Django dicts

[ 
    { 
    "fixed_key_1": "foo1", 
    "fixed_key_2": { 
     "random_key_1": "bar1", 
     "random_key_2": "bar2", 
    } 
    }, 
    { 
    "fixed_key_1": "foo2", 
    "fixed_key_2": { 
     "random_key_3": "bar2", 
     "random_key_4": "bar3", 
    } 
    } 
] 

मैं चाहता हूँ:

class Test(TimeStampedModel): 
    actions = JSONField() 

चलो कहते हैं कि कार्रवाई JSONField इस तरह दिखता है चलो सूची के प्रत्येक आइटम के लिए foo1 और foo2 कुंजी फ़िल्टर करने में सक्षम हो। जब मैं कार्य करें:

>>> Test.objects.filter(actions__1__fixed_key_1="foo2") 

टेस्ट क्वेरीसमूह में है। लेकिन जब मैं करता हूं:

>>> Test.objects.filter(actions__0__fixed_key_1="foo2") 

यह नहीं है, जो समझ में आता है। मैं की तरह कुछ करना चाहता हूँ:

>>> Test.objects.filter(actions__values__fixed_key_1="foo2") 

या

>>> Test.objects.filter(actions__values__fixed_key_2__values__contains="bar3") 

और क्वेरीसमूह में टेस्ट की है।

कोई विचार अगर यह किया जा सकता है और कैसे?

उत्तर

2

आप django-jsonfield पैकेज का उपयोग कर सकते हैं, मुझे लगता है कि यह पहले से ही आप उपयोग कर रहे हैं।

from jsonfield import JSONField 
class Test(TimeStampedModel): 
    actions = JSONField() 

तो एक विशिष्ट प्रॉपर्टी के साथ एक खोज बनाने के लिए खोज करने के लिए, तो आप सिर्फ यह कर सकते हैं:

def test_filter(**kwargs): 
    result = Test.objects.filter(actions__contains=kwargs) 
    return result 

आप PostgreSQL का उपयोग कर रहे हैं, तो हो सकता है आप PostgreSQL specific model fields का लाभ ले सकते।

पीएस: यदि आप बहुत से JSON संरचना से निपट रहे हैं तो आपको शायद NoSQL डेटाबेस का उपयोग करने पर विचार करना होगा।

+1

मैं वास्तव में पहले से ही PostgreSQL के JSONField विशिष्ट मॉडल फ़ील्ड का उपयोग कर रहा हूं ('django.contrib.postgres.fields से आयात JSONField')।आपका समाधान तब काम करता है जब 'your_property' ज्ञात होता है (' fixed_key_1' और 'fixed_key_2' मेरे मामले में) लेकिन जब मैं' your_property' ('random_key_ #' को अपने मामले में नहीं जानता) तो मैं कैसे कर सकता हूं? – Scentle5S

+0

आपको '{' fixed_key_1 ':' foo2 '}' अपने पैरामीटर बनाना चाहिए, मैंने जेनेरिक फ़ंक्शन के साथ कोड अपडेट किया है। – DhiaTN

+1

बात यह है कि मैं विशेष रूप से 'your_property' नहीं जानता हूं। यह कुछ भी हो सकता है और मुझे इसके बारे में भी परवाह नहीं है, सिर्फ यह जानना है कि JSONField में गहराई के बावजूद, इसके किसी भी मूल्य में दी गई स्ट्रिंग है या नहीं। – Scentle5S

2

आपको दस्तावेज के रूप में, इसके लिए __contains लुकअप का उपयोग करने में सक्षम होना चाहिए। लुकअप अभी भी धियाटीएनएन की सिफारिश की तरह होगा। तो, कुछ इस तरह काम करना चाहिए:

Test.objects.filter(actions__contains=[{'fixed_key_1': 'foo2'}]) 

यह सूची जाएगा:

Test.objects.filter(actions__contains={'fixed_key_1': 'foo2'}) 
15

आप dicts के अपने सरणी में क्षेत्रों में से एक से अपने डेटा को फ़िल्टर करने के लिए wan't, तो आप इस क्वेरी कोशिश कर सकते हैं सभी Test ऑब्जेक्ट्स जिनमें कम से कम एक ऑब्जेक्ट actions फ़ील्ड है जिसमें मान fixed_key_1 शामिल है।

यह भी नेस्टेड देखने के लिए काम करना चाहिए, भले ही आप वास्तविक अनुक्रमित नहीं जानता: सरल शब्दों में

Test(actions=[ 
    {'fixed_key_1': 'foo4', 'fixed_key_3': [ 
     {'key1': 'foo2'}, 
    ]} 
}).save() 

Test.objects.filter(actions__contains=[{'fixed_key_3': [{'key1': 'foo2'}]}]) 

, बाकी सब पर ध्यान नहीं देगा शामिल हैं।

दुर्भाग्यवश, यदि नेस्टेड तत्व एक वस्तु है, तो आपको मुख्य नाम पता होना चाहिए। मूल्य से लुकअप उस मामले में काम नहीं करेगा।