如何在Django的JSONField中正确存储与获取布尔值?
如何在Django JSONField中便捷存储和读取布尔值?
在Django后台管理中向JSONField输入数据时,无法直接输入原生布尔值,只能存入字符串、浮点数或整数,导致读取时原本期望的布尔值变成了"True"/"False"字符串类型。比如:
obj.params = {"fast": 3, "slow": 6, "shift": "True", "signal": 2} obj.save() > obj.params['shift'] 'True'
虽然可以用字典推导式手动转换类型,但有更简便的方案:
方案1:自定义JSONField自动处理类型转换
通过继承默认的JSONField,重写to_python方法,自动将字符串形式的"True"/"False"转换为原生布尔值:
import json from django.db import models def convert_bool_strings(obj): if isinstance(obj, dict): return {k: convert_bool_strings(v) for k, v in obj.items()} elif isinstance(obj, str): lower_v = obj.lower() if lower_v == 'true': return True elif lower_v == 'false': return False return obj class BoolAwareJSONField(models.JSONField): def to_python(self, value): # 先调用父类的to_python处理基础JSON解析 parsed_value = super().to_python(value) # 再递归转换布尔字符串 return convert_bool_strings(parsed_value)
在模型中使用这个自定义字段替代默认JSONField:
class YourModel(models.Model): params = BoolAwareJSONField(default=dict)
之后无论从后台输入"True"/"False"还是在代码中存入原生布尔值,读取时都会得到正确的布尔类型。
方案2:在模型save方法中预处理数据
如果不想自定义字段,可以在模型保存前自动转换字符串布尔值:
class YourModel(models.Model): params = models.JSONField(default=dict) def save(self, *args, **kwargs): def convert_value(val): if isinstance(val, str): lower_val = val.lower() if lower_val == 'true': return True elif lower_val == 'false': return False return val # 遍历params字典转换值 self.params = {key: convert_value(val) for key, val in self.params.items()} super().save(*args, **kwargs)
这样在调用obj.save()时,所有字符串形式的布尔值会被自动转为原生布尔类型存储。
方案3:用@property定义便捷读取属性
如果只需要在读取时转换,不修改存储的数据,可以定义一个属性来返回转换后的参数:
class YourModel(models.Model): params = models.JSONField(default=dict) @property def parsed_params(self): def convert(val): if isinstance(val, str): lower_val = val.lower() if lower_val == 'true': return True elif lower_val == 'false': return False return val return {k: convert(v) for k, v in self.params.items()}
读取时直接使用obj.parsed_params['shift']就能获取到布尔值,无需每次手动写推导式。
内容的提问来源于stack exchange,提问作者Florent
相关产品推荐
相关产品推荐

