Django 1.9 JSONField更新行为 [英] Django 1.9 JSONField update behavior
问题描述
类Activity(models.Model):
activity_id = models.CharField(max_length = MAX_URL_LENGTH ,db_index = True,unique = True)
my_data = JSONField(default = dict())
这是我正在做的一个例子:
>>>从proj导入模型
>>>> test,created = models.Activity.objects.get_or_create(activity_id =foo)
>>>创建
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'
似乎每当我更新<$ c中的任何字段$ c> my_data ,我创建的下一个对象使用前一个对象的 my_data
中的数据预先填充自己。无论是使用 get_or_create
还是仅使用创建
,都会发生这种情况。有人可以向我解释发生了什么吗?
问题是你使用 default = dict ()
。 Python字典是可变的。当模型文件加载时,默认字典将创建一次。之后,如果使用默认值,对 instance.my_data
的任何更改都会更改相同的实例。
解决方案是使用可调用的 dict
作为默认值,而不是 dict()
。
class Activity(models.Model):
pre>
my_data = JSONField(default = dict)
JSONField文档警告:
如果您给该字段一个
默认值
,确保它是一个可调用的,例如
dict
(为空默认)或可调用返回一个dict
(如功能)。不正确地使用default = {}
创建一个可变的默认值,它在JSONField
的所有实例之间共享。
I've recently updated to Django 1.9 and tried updating some of my model fields to use the built-in JSONField (I'm using PostgreSQL 9.4.5). As I was trying to create and update my object's fields, I came across something peculiar. Here is my model:
class Activity(models.Model): activity_id = models.CharField(max_length=MAX_URL_LENGTH, db_index=True, unique=True) my_data = JSONField(default=dict())
Here is an example of what I was doing:
>>> 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'
It seems whenever I update any field in
my_data
, the next object I create pre-populates itself with the data frommy_data
from the previous object. This happens whether I useget_or_create
or justcreate
. Can someone explain to me what is happening?解决方案The problem is that you are using
default=dict()
. Python dictionaries are mutable. The default dictionary is created once when the models file is loaded. After that, any changes toinstance.my_data
alter the same instance, if they are using the default value.The solution is to use the callable
dict
as the default instead ofdict()
.class Activity(models.Model): my_data = JSONField(default=dict)
The JSONField docs warn about this:
If you give the field a
default
, ensure it’s a callable such asdict
(for an empty default) or a callable that returns adict
(such as a function). Incorrectly usingdefault={}
creates a mutable default that is shared between all instances ofJSONField
.
这篇关于Django 1.9 JSONField更新行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!