Django 1.9 JSONField更新行为 [英] Django 1.9 JSONField update behavior

查看:272
本文介绍了Django 1.9 JSONField更新行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 类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):
my_data = JSONField(default = dict)
pre>

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 from my_data from the previous object. This happens whether I use get_or_create or just create. 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 to instance.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 of dict().

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

这篇关于Django 1.9 JSONField更新行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆