为什么具有 JSONFields 的不同 Django 模型具有相同的值?
Why do different Django Models with JSONFields have the same values?
我有一个带有 JSONField 的模型(仅限 Postgres 的字段):
models.py:
from django.db import models
from django.contrib.postgres.fields import JSONField
class Mod(models.Model):
data = JSONField(default={ 'name':'Model' })
所以我创建了 2 个模型 – ./manage.py shell
:
>>> from m3d.models import Mod
>>> m1 = Mod()
>>> m1.save()
>>> m2 = Mod()
>>> m2.data['name'] = 'Model 2'
>>> m2.save()
但它们具有相同的 data['name']
值:
>>> m1.data['name']
'Model 2'
>>> m2.data['name']
'Model 2'
请注意,数据库中的值不同:
>>> m1a = Mod.objects.get(pk=m1.pk) # get m1 data from db
>>> m1a.data['name']
'Model'
>>> m2.data['name']
'Model 2'
但是变量 m1
的值仍然是 Model 2
。
我错过了什么吗?这是我需要解决的某种行为吗?
仅供参考:使用 Django 2.0.1
documentation 中对此进行了介绍。您为字段设置 default
的方式不正确:
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.
这是您所看到的行为,您创建的实例之间共享同一个对象,并且修改一个会导致另一个也被更改。
您需要改用可调用对象,例如:
def get_default_data():
return { 'name':'Model' }
class Mod(models.Model):
data = JSONField(default=get_default_data)
我有一个带有 JSONField 的模型(仅限 Postgres 的字段):
models.py:
from django.db import models
from django.contrib.postgres.fields import JSONField
class Mod(models.Model):
data = JSONField(default={ 'name':'Model' })
所以我创建了 2 个模型 – ./manage.py shell
:
>>> from m3d.models import Mod
>>> m1 = Mod()
>>> m1.save()
>>> m2 = Mod()
>>> m2.data['name'] = 'Model 2'
>>> m2.save()
但它们具有相同的 data['name']
值:
>>> m1.data['name']
'Model 2'
>>> m2.data['name']
'Model 2'
请注意,数据库中的值不同:
>>> m1a = Mod.objects.get(pk=m1.pk) # get m1 data from db
>>> m1a.data['name']
'Model'
>>> m2.data['name']
'Model 2'
但是变量 m1
的值仍然是 Model 2
。
我错过了什么吗?这是我需要解决的某种行为吗?
仅供参考:使用 Django 2.0.1
documentation 中对此进行了介绍。您为字段设置 default
的方式不正确:
If you give the field a default, ensure it’s a callable such as
dict
(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 of JSONField.
这是您所看到的行为,您创建的实例之间共享同一个对象,并且修改一个会导致另一个也被更改。
您需要改用可调用对象,例如:
def get_default_data():
return { 'name':'Model' }
class Mod(models.Model):
data = JSONField(default=get_default_data)