I'm getting data from an API and saving into a list called data[].
After this, I'm sending these data to another class to format it.
I want to create a dict, so I can save these data. I'm trying to do something like this:
import json
import datetime
class MovieFormatter():
def format(self, data):
data = {
"movie_info_name": data['title']
"movie_info_duration": data['duration']
"movie_info_description": data['synopsis']
"movie_info_genres": data['genres']
"movie_info_actor": data['cast']
"movie_info_director": data['director']
data['trailers'] = data.get('trailers') or []
"dictionary": [{'url': x['url'], 'type': x['type']} for x in data['images'] + data['trailers']]
}
return data
Is this the right way to do?
It seems that the data object passed to your function is already a dictionary, from the way it has been indexed e.g. data['title'].
Try this :
_in_data = ["a","b","c"]
_out_data = ["x","y","z"]
_dict={}
print(_dict)
for i in range (len(_in_data)):
_dict[_in_data[i]]=_out_data[i]
print(_dict)
Related
I have the following model:
class Car(models.Model):
data = models.TextField(default="[]")
Also, I have the following serializer:
class CarSerializer(serializers.ModelSerializer):
data = serializers.ListField(child=serializers.CharField())
The REST API gets data and saves it as text field. In my to_dict method of Car, I want to convert self.data into JSON and return the dict:
def to_dict(self):
result = dict()
result['data']= json.loads(self.data)
return result
But it fails with the error:
json.decoder.JSONDecodeError: Expecting value: line 1 column 2 (char 1)
As I understand, the reason is that self.data is:
"['a', 'b', 'c']"
And not:
'["a", "b", "c"]'
I'm familiar with JsonField, but since I'm using SQLite without JSON1 externation, I can't use it. How can I convert self.data to JSON?
You can use python json.dumps() method to convert string into json format and then use json.loads() to convert json into python object.
import json
def to_dict(self):
result = dict()
data = json.dumps(self.data)
result['data'] = json.loads(data)
return result
The simplest way to solve this problem is json.loads(self.data.replace('\'','\"')).
Replace ' to ".
Or you can try eval(self.data)
you can watch a sample here about the usage of eval
I am getting Data via a REST-Interface and I want to store those data in a class-object.
my class could looks like this:
class Foo:
firstname = ''
lastname = ''
street = ''
number = ''
and the json may look like this:
[
{
"fname": "Carl",
"lname": "any name",
"address": ['carls street', 12]
}
]
What's the easiest way to map between the json and my class?
My problem is: I want to have a class with a different structure than the json.
I want the names of the attributes to be more meaningful.
Of course I know that I could simply write a to_json method and a from_json method which does what I want.
The thing is: I have a lot of those classes and I am looking for more declarative way to write the code.
e.g. in Java I probably would use mapstruct.
Thanks for your help!
Use a dict for the json input. Use **kwargs in an __init__ method in your class and map the variables accordingly.
I had a similar problem, and I solved it by using #classmethod
import json
class Robot():
def __init__(self, x, y):
self.type = "new-robot"
self.x = x
self.y = y
#classmethod
def create_robot(cls, sdict):
if sdict["type"] == "new-robot":
position = sdict["position"]
return cls(position['x'], position['y'])
else:
raise Exception ("Unable to create a new robot!!!")
if __name__=='__main__':
input_string = '{"type": "new-robot", "position": {"x": 3, "y": 3}}'
cmd = json.loads(input_string)
bot = Robot.create_robot(cmd)
print(bot.type)
Perhaps you could you two classes, one directly aligned with the Json (your source class) and the other having the actual structure you need. Then you could map them using the ObjectMapper class[https://pypi.org/project/object-mapper/]. This is very close to the MapStruct Library for Java.
ObjectMapper is a class for automatic object mapping. It helps you to create objects between project layers (data layer, service layer, view) in a simple, transparent way.
I have the following model:
class BaseTransaction(models.Model):
"""Model to store JSON data"""
name = models.CharField(max_length=255)
json_data = JSONField(null=True)
If I create an instance with the following data:
base_transaction = models.BaseTransaction.objects.create(
name="Test Transaction",
json_data={{"sales": 3.24, "date": "2020-06-05"},
{"sales": 5.50, "date": "2020-06-04"},
{"sales": 256.53, "date": "2020-06-02"}}
)
How would I access the second row of data without a key? Or is this the wrong format for JSON? I am using this format because the original data is from a CSV and this is how it converts to JSON.
No, the above structure is not inJSON format. You can always validate if it's JSON or not using JSON Formatter & Validator
You would want to restructure is according to the rules of JSON, and manually if that can be done so. Once it's in JSON format, you can access the second row without keys using a for loop and a counter, e.g.
counter = 0
for (key in obj) {
counter+=1
if (counter == 2):
# Do anything
else:
print("Key: " + key)
print("Value: " + obj[key])
}
I have the below list from which I have to retrieve the port number I want the value 50051 but what I get is port=50051 I know I can retrieve this by iterating the list and using string operations but wanted to see if there is some direct way to access this.
r = requests.get(url_service)
data = {}
data = r.json()
#Below is the json after printing
[{'ServerTag': [ 'abc-service=true',
'port=50051',
'protocol=http']
}]
print(data[0]["ServiceTags"][1]) // prints port=50051
You can do something like this perhaps:
received_dic = {
'ServerTag': [ 'abc-service=true',
'port=50051',
'protocol=http']
}
ServerTag = received_dic.get("ServerTag", None)
if ServerTag:
port = list(filter(lambda x: "port" in x, ServerTag))[0].split("=")[1]
print(port)
# 50051
Considering you have the following JSON:
[
{
"ServerTag": ["abc-service=true", "port=50051", "protocol=http"]
}
]
You can extract your value like this:
from functools import partial
# ...
def extract_value_from_tag(tags, name, default=None):
tags = map(partial(str.split, sep='='), tags)
try:
return next(value for key, value in tags if key == name)
except StopIteration:
# Tag was not found
return default
And then you just:
# Providing data is the deserialized JSON as a Python list
# Also assuming that data is not empty and ServerTag is present on the first object
tags = data[0].get('ServerTag', [])
port_number = extract_value_from_tag(tags, 'port', default='8080')
I have min max variables that are a result of query on model
args.aggregate(Min('price'))
args.aggregate(Max('price'))
returning the serialized data like this
return HttpResponse(json.dumps([{"maxPrice":args.aggregate(Max('price')),
"minPrice":args.aggregate(Min('price'))}]), content_type ='application/json')
the result looks like this:
minPrice = {
"price__min" = 110;
};
maxPrice = {
"price__max" = 36000;
};
and extracting the data looks like this
...
success:^(AFHTTPRequestOperation *operation, id responseObject){
NSDictionary *elements = responseObject;
int minPrice = elements[0][#"minPrice"][#"price__min"];
}
The Question: how to change the django/python code in order for the objective-c code to look like this: int minPrice = elements[#"minPrice"];
data = args.aggregate(minPrice=Min('price'), maxPrice=Max('price'))
return HttpResponse(json.dumps(data), content_type='application/json')
data variable is a dictionary with "minPrice" and "maxPrice" keys.
Dump to JSON a dictionary instead of a list:
values = args.aggregate(Min('price'), Max('price'))
return HttpResponse(json.dumps({'maxPrice': values['price__max'],
'minPrice': values['price__min']}),
content_type ='application/json')
Well you could do something like this to rearrange the json dump:
data = {'maxPrice': args.aggregate(Max('price'))['price__max'],
'minPrice': args.aggregate(Min('price'))['price__min']}
return HttpResponse(json.dumps(data), content_type ='application/json')
That should give you a json dict of that form '{"maxPrice": xxx, "minPrice": yyy}'.