我的模型中有一个 JSON 字段,通过使用 values 选项,我想获取 JSON 字段中存在的键值。
假设我的 JSON 字段值为:
{"key1":"value1","key2":"value2"}
MyClass.objects.values("field1","field2","JSON Key")
让 JSON Key 为“Key1”
预期的 O/P:
[{field1:Value1,field2:value2,Key1:value1}]
我的模型中有一个 JSON 字段,通过使用 values 选项,我想获取 JSON 字段中存在的键值。
假设我的 JSON 字段值为:
{"key1":"value1","key2":"value2"}
MyClass.objects.values("field1","field2","JSON Key")
让 JSON Key 为“Key1”
预期的 O/P:
[{field1:Value1,field2:value2,Key1:value1}]
更好的解决方案(对于 Django >= 1.11)是使用 KeyTextTransform,如下所示:
from django.contrib.postgres.fields.jsonb import KeyTextTransform
MyModel.objects\
.annotate(key1=KeyTextTransform('key1', 'myjsonfield'))\
.values('field1','field2','key1')
我在 ActiveQuerySet 中编写了一个自定义管理器函数,它接受字段列表并从对象中获取特定字段信息。
我已经为简单的 json 结构编写了脚本。但是你可以根据需要改变处理 json 的方式。
ActiveQuerySet 类如下。
class ActiveQuerySet(models.QuerySet):
def custom_values(self,*args,**kwargs):
model_fields = self.model._meta.get_fields()
model = [str(i.name) for i in model_fields]
json_fields = [str(i.name) for i in model_fields if i.get_internal_type() == 'JSONField']
responses = []
for one in self:
one_value = {}
for i in args[0]:
if i in model: # search if field is in normal model
one_value[i]=str(getattr(one,i))
else:
for jf in json_fields: #get all json fields in model
try:
json_value = eval(getattr(one,jf)) #eval to json or dict format if required
except:
json_value = getattr(one,jf)
json_keys = json_value.keys() #get the keys from json data stored
if i in json_keys:#check if key is present
one_value[i] = json_value[i]
responses.append(one_value)
return responses
MyModel.objects.all().custom_values(['field1','field2','key(which is present in JOSN field)'])
假设我的 json 数据存储为
{"cluster": "Mulchond", "2962": "2016-12-13", "2963": "1", "2964": "4", "2965": "0", "2966": "0", "2967": "0", "2968": "0.0318", "2969": "0.0705", "2970": "", "2971": "", "2972": "", "2973": "17.256", "2974": "48.8351", "2975": "142", "2976": "783", "2977": "276", "2978": "0.05237", "2979": "70", "2980": "0.05237", "2981": "", "2982": "", "2983": "", "2984": "142", "2985": "32", "2986": "", "2987": "20.773551", "2988": "73.649422"}
从这里我想得到键'2988'的值,我的查询就像
MyModel.objects.filter().custom_values(['id','2988'])
o/p:
[{'2987': '20.730995', 'id': '66302'},
{'2987': '20.766556', 'id': '66303'},
{'2987': '20.773551', 'id': '66304'}]
其中 'id 由 Django 生成,'2987' 是 JSON 字段中存在的一个键