Mallik Sai
Mallik Sai

Reputation: 186

Fetch Json Field value using Values in Django

I have a JSON field in my model and by using values option, I would like to get the key value present in the JSON field.

Assume my JSON field value is:

{"key1":"value1","key2":"value2"}


MyClass.objects.values("field1","field2","JSON Key")

Let JSON Key be "Key1"

Expected O/P:

 [{field1:Value1,field2:value2,Key1:value1}] 

Upvotes: 2

Views: 3349

Answers (2)

Mallik Sai
Mallik Sai

Reputation: 186

I have written a custom manager function in ActiveQuerySet which accepts a list of fields and give get the particular field information from the object.

I have written the script for simple json structure..but where as u can change the way of processing json according to requirement.

The ActiveQuerySet class is as below.

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)'])

Assume my json data is stored as

{"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"}

from this I want to get value of key '2988', My Query be like

MyModel.objects.filter().custom_values(['id','2988'])

o/p :

[{'2987': '20.730995', 'id': '66302'},
 {'2987': '20.766556', 'id': '66303'},
 {'2987': '20.773551', 'id': '66304'}]

where 'id is generated by Django and '2987' is one key which is present in JSON Field

Upvotes: 0

simon
simon

Reputation: 16280

A better solution (for Django >= 1.11) would be to use KeyTextTransform, like so:

from django.contrib.postgres.fields.jsonb import KeyTextTransform
MyModel.objects\
    .annotate(key1=KeyTextTransform('key1', 'myjsonfield'))\
    .values('field1','field2','key1')

Upvotes: 3

Related Questions