带有整数键的 Django JSONField 数据
Django JSONField data with integer keys
我想用带有整数键的 JSON 字典保存模型实例,例如 {2: 3}
。
但是保存后我的字典变成了{"2": 3}
。有没有办法将整数键保存到 JSON?
class MyModel(models.Model):
data = JSONField("data")
record = MyModel.objects.create(
data={2: 3},
)
record.refresh_from_db()
print(record.data)
# > {"2": 3}
# And I want record.data == {2: 3}
from django.contrib.postgres.fields import JSONField
和现代 from django.db.models import JSONField
的行为相同
I want to save a model instance with JSON dict with integer keys, like {2: 3}
.
那是不可能的:JSON specifications说键是总是字符串。 Python 中的 JSON 序列化程序会将键转换为对应的字符串(也许在这种情况下引发错误更合适)。
如果所有键都是整数,您可以创建一个 JSONField
的子类,它会自动将键转换为整数,例如:
from django.db.models import JSONField
def outer_json_is_object(value):
if not isinstance(value, dict):
raise ValidationError(_('Outer JSON item should be an object'), code='invalid_json_object')
class IntKeyJSONField(JSONField):
def __init__(self, *args, **kwargs):
validators = kwargs.setdefault('validators', [])
validators.append(outer_json_is_object)
super().__init__(*args, **kwargs)
def from_db_value(self, value, expression, connection):
value = super().from_db_value(value, expression, connection)
if value is not None:
return { <strong>int(k)</strong>: v for k, v in value.items() }
然后它将外键转换为 JSON 对象的整数。因此,您可以使用 IntKeyJSONField
,但这确实 而不是 将键存储为整数,因为这又是无效的 JSON,我们所做的我们是从 JSON 读取时 post-process 字典,因此用 int
对应的键替换键。
我想用带有整数键的 JSON 字典保存模型实例,例如 {2: 3}
。
但是保存后我的字典变成了{"2": 3}
。有没有办法将整数键保存到 JSON?
class MyModel(models.Model):
data = JSONField("data")
record = MyModel.objects.create(
data={2: 3},
)
record.refresh_from_db()
print(record.data)
# > {"2": 3}
# And I want record.data == {2: 3}
from django.contrib.postgres.fields import JSONField
和现代 from django.db.models import JSONField
I want to save a model instance with JSON dict with integer keys, like
{2: 3}
.
那是不可能的:JSON specifications说键是总是字符串。 Python 中的 JSON 序列化程序会将键转换为对应的字符串(也许在这种情况下引发错误更合适)。
如果所有键都是整数,您可以创建一个 JSONField
的子类,它会自动将键转换为整数,例如:
from django.db.models import JSONField
def outer_json_is_object(value):
if not isinstance(value, dict):
raise ValidationError(_('Outer JSON item should be an object'), code='invalid_json_object')
class IntKeyJSONField(JSONField):
def __init__(self, *args, **kwargs):
validators = kwargs.setdefault('validators', [])
validators.append(outer_json_is_object)
super().__init__(*args, **kwargs)
def from_db_value(self, value, expression, connection):
value = super().from_db_value(value, expression, connection)
if value is not None:
return { <strong>int(k)</strong>: v for k, v in value.items() }
然后它将外键转换为 JSON 对象的整数。因此,您可以使用 IntKeyJSONField
,但这确实 而不是 将键存储为整数,因为这又是无效的 JSON,我们所做的我们是从 JSON 读取时 post-process 字典,因此用 int
对应的键替换键。