2016-02-18 23 views
5

Kısa bir süre önce Django 1.9'a güncelledik ve yerleşik JSONField'ı (PostgreSQL 9.4.5 kullanıyorum) kullanmak için bazı model alanlarını güncellemeyi denedim. Nesnemin alanlarını yaratmaya ve güncellemeye çalışırken, kendine has bir şeyle karşılaştım. Ben my_data herhangi bir alanı güncelleştirmek zamanDjango 1.9 JSONField güncelleştirme davranışı

>>> 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' 

Ben oluşturmak sonraki nesne kendisini önceden doldurur, görünüyor: İşte

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

Ne yaptığımı bir örnektir: İşte benim modelidir Önceki nesneden my_data veri. Bu, get_or_create kullanmam veya sadece create kullanmam olur. Birisi bana neler olduğunu açıklayabilir mi?

cevap

17

Sorun, default=dict() kullanıyor olmanızdır. Python sözlükleri değiştirilebilir. Varsayılan dosya, model dosyası yüklendiğinde bir kez oluşturulur. Bundan sonra, instance.my_data'daki herhangi bir değişiklik, varsayılan değeri kullanıyorlarsa aynı örneği değiştirir.

Çözüm, yerine varsayılan olarak callable dict'u kullanmaktır.

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

JSONField docs bu konuda uyarmak:

Eğer alanını bir default verirsek (boş bir varsayılan için) çağrılabilir böyle dict olarak var veya dict döndüren bir çağrılabilir (örneğin sağlamak bir işlev). Yanlış default={} kullanılarak JSONField tüm örneklerini arasında paylaşılan bir değişken varsayılan oluşturur.

+0

Vay canına kadar değişmiş olabileceğini düşündüm. Bu basit hataya dikkat ettiğiniz için teşekkürler! – user994013

İlgili konular