带有整数键的 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 对应的键替换键。