2016-02-18 18 views
5

Gần đây tôi đã cập nhật lên Django 1.9 và đã thử cập nhật một số trường mô hình của tôi để sử dụng JSONField tích hợp (tôi đang sử dụng PostgreSQL 9.4.5). Khi tôi đang cố gắng tạo và cập nhật các lĩnh vực của đối tượng của mình, tôi bắt gặp một điều gì đó kỳ lạ. Đây là mô hình của tôi:Django 1.9 Hành vi cập nhật JSONField

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

Dưới đây là một ví dụ về những gì tôi đã làm:

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

Dường như bất cứ khi nào tôi cập nhật bất kỳ lĩnh vực trong my_data, đối tượng kế tiếp tôi tạo trước populates bản thân với dữ liệu từ my_data từ đối tượng trước đó. Điều này xảy ra cho dù tôi sử dụng get_or_create hoặc chỉ create. Ai đó có thể giải thích cho tôi điều gì đang xảy ra?

Trả lời

17

Vấn đề là bạn đang sử dụng default=dict(). Từ điển Python có thể thay đổi được. Từ điển mặc định được tạo một lần khi tệp mô hình được tải. Sau đó, mọi thay đổi đối với instance.my_data sẽ thay đổi cùng một trường hợp, nếu chúng đang sử dụng giá trị mặc định.

Giải pháp là sử dụng số gọi dict làm mặc định thay vì dict().

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

Các JSONField docs cảnh báo về vấn đề này:

Nếu bạn cung cấp cho các lĩnh vực một default, đảm bảo đó là một callable như dict (đối với một mặc định trống) hoặc một callable mà trả về một dict (ví dụ như một hàm). Sử dụng sai default={} tạo mặc định có thể thay đổi được chia sẻ giữa tất cả các phiên bản JSONField.

+0

Wow Tôi nghĩ mình đã thay đổi nó thành có thể gọi được. Cảm ơn bạn đã chỉ ra rằng sai lầm đơn giản! – user994013

Các vấn đề liên quan