python - Django 1.9 JSONField 更新行为

标签 python json django postgresql

我最近更新到 Django 1.9 并尝试更新我的一些模型字段以使用内置的 JSONField(我使用的是 PostgreSQL 9.4.5)。当我尝试创建和更新我的对象的字段时,我遇到了一些奇怪的事情。这是我的模型:

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

这是我正在做的一个例子:

>>> 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 中的任何字段时,我创建的下一个对象都会使用前一个对象的 my_data 中的数据预先填充自身。无论我使用 get_or_create 还是仅使用 create,都会发生这种情况。有人可以向我解释发生了什么吗?

最佳答案

问题是您正在使用 default=dict()。 Python 字典是可变的。默认字典在加载模型文件时创建一次。之后,对 instance.my_data 的任何更改都会改变同一个实例,如果它们使用默认值的话。

解决方案是使用可调用的 dict 作为默认值,而不是 dict()

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

JSONField docs对此发出警告:

If you give the field a default, ensure it’s a callable such as dict (for an empty default) or a callable that returns a dict (such as a function). Incorrectly using default={} creates a mutable default that is shared between all instances of JSONField.

关于python - Django 1.9 JSONField 更新行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35483301/

相关文章:

python - docker/matplotlib : RuntimeError: Invalid DISPLAY variable

mysql - 如何使用 xampp mysql 配置 django?

ios - 使用 JSON 数据填充 tableView

python - 给出 JSONDecodeError : Expecting , 分隔符的有效 JSON

python - 使用 ix 或 iloc 检查 pandas DataFrame 中的特定值(在单元格中)是否为 NaN 不工作

python - 如何选择带有边界框的 numpy 二维数组中唯一元素的所有位置?

c# - 在 C# 中,当一个字段可能是字符串或字符串数​​组时,如何反序列化此 json?

javascript - 从 JSON 构建动态表

python - 如何通过过滤的桥接表字段对查询集进行排序?

python - Ckeditor 在创建后仍然隐藏 - editor.css 为空