2016-02-18 21 views
5

मैंने हाल ही में Django 1.9 में अपडेट किया है और अंतर्निहित JSONField (मैं PostgreSQL 9.4.5 का उपयोग कर रहा हूं) का उपयोग करने के लिए अपने कुछ मॉडल फ़ील्ड को अपडेट करने का प्रयास किया है। जैसे ही मैं अपने ऑब्जेक्ट के खेतों को बनाने और अपडेट करने की कोशिश कर रहा था, मैं कुछ असाधारण में आया।Django 1.9 JSONField अद्यतन व्यवहार

>>> from proj import models 
>>> test, created = models.Activity.objects.get_or_create(activity_id="foo") 
>>> created 
True 
>>> test.my_data['id'] = "foo" 
>>> test.save() 
>>> test 
<Activity: {"id": "foo"}> 
>>> test2, created2 = models.Activity.objects.get_or_create(activity_id="bar") 
>>> created2 
True 
>>> test2 
<Activity: {"id": "foo"}> 
>>> test2.activity_id 
'bar' 
>>> test.activity_id 
'foo' 

ऐसा लगता है जब भी मैं my_data में किसी भी क्षेत्र अद्यतन करते हैं, अगले ऑब्जेक्ट मैं बनाने के साथ ही पूर्व भरता है:

class Activity(models.Model): 
    activity_id = models.CharField(max_length=MAX_URL_LENGTH, db_index=True, unique=True) 
    my_data = JSONField(default=dict()) 

यहाँ मैं क्या कर रहा था का एक उदाहरण है: यहाँ मेरी मॉडल है पिछली वस्तु से my_data से डेटा। ऐसा होता है कि मैं get_or_create या केवल create का उपयोग करता हूं। क्या कोई मुझे बता सकता है कि क्या हो रहा है?

उत्तर

17

समस्या यह है कि आप default=dict() का उपयोग कर रहे हैं। पाइथन शब्दकोश म्यूटेबल हैं। मॉडल फ़ाइल लोड होने पर डिफ़ॉल्ट शब्दकोश एक बार बनाया जाता है। उसके बाद, instance.my_data में कोई भी परिवर्तन उसी उदाहरण को बदलता है, यदि वे डिफ़ॉल्ट मान का उपयोग कर रहे हैं।

समाधान dict को dict() के बजाय डिफ़ॉल्ट के रूप में उपयोग करने का है।

class Activity(models.Model): 
    my_data = JSONField(default=dict) 

JSONField docs इस बारे में चेतावनी:

आप क्षेत्र एक default देते हैं, सुनिश्चित करें कि यह (एक खाली डिफ़ॉल्ट के लिए) एक प्रतिदेय ऐसे dict के रूप में है या एक प्रतिदेय (जैसे कि एक dict रिटर्न एक समारोह)। default={} का गलत उपयोग करने से एक म्यूटेबल डिफ़ॉल्ट बनाता है जिसे JSONField के सभी उदाहरणों के बीच साझा किया जाता है।

+0

वाह मैंने सोचा कि मैंने इसे कॉल करने योग्य में बदल दिया है। उस साधारण गलती को इंगित करने के लिए धन्यवाद! – user994013

संबंधित मुद्दे