Expecting JSON object instead of JSON Array - json

In my django application with database engine djongo, I'm trying to return a JSON response by retrieving from my database. But, I'm receiving JSON array instead of JSON object. Currently, there is only one record in my database. Please see the code below.
model.py
class bloodDonors(models.Model):
location=models.CharField(max_length=20)
name=models.CharField(max_length=20)
phone=models.IntegerField()
address=models.TextField()
bloodGroup=models.CharField(max_length=5)
type=models.CharField(max_length=20)
def __str__(self):
return self.name
views.py
class bloodDonersView(viewsets.ModelViewSet):
queryset = bloodDonors.objects.all()
serializer_class = bloodDonorsSerializer
JSON Reponse:
[
{
"id": 3,
"location": "Delhi",
"name": "Tony",
"phone": 888,
"address": "South street",
"bloodGroup": "B+",
"type": "blood-donation"
}
]
But, actually I needed the response as given below:
{
"id": 3,
"location": "Delhi",
"name": "Tony",
"phone": 888,
"address": "South street",
"bloodGroup": "B+",
"type": "blood-donation"
}

It sounds like you are using the 'list' endpoint that retrieves all objects matching the queryset, but you want to be using the detail retrieve endpoint, where you just retrieve one object. The good news is that because you are using a Model viewset, you get a detail retrieve GET endpoint for free. All you have to do is pass in the pk of the object you want as part of the url and it will return only the single object you requested.
So if your url is currently:
/api/v1/blood-donors
you'd want to use the url:
/api/v1/blood-donors/3
to get just the single object you want (with pk=3). The GET endpoint with no /{PK} at the end is always going to return a list, even if there's only one object in your database, and if you add the pk to the url you will always only get one object back, the object that matches the pk you pass in.
Update to answer your question in the comment. The new method would look something like this:
class bloodDonersView(viewsets.ModelViewSet):
queryset = bloodDonors.objects.all()
serializer_class = bloodDonorsSerializer
#action(detail=False, methods=['get',], url_path='first')
def get_first_object(self, request):
object = bloodDonors.objects.first()
serializer = bloodDonorsSerializer(object, many=False)
return response.Response(serializer.data)
the url you would use is
api/v1/blood-donors/first
and you need to check the documentation about where to import response and the action decorator.

Related

Decode resulting json and save into db - Django + Postgres

I have a model like this:
class MyClass(models.Model):
typea = models.CharField(max_length=128)
typeb = models.CharField(max_length=128)
If for example, the resulting json from an API is like this:
{
"count": 75,
"results": [
{
"typea": "This tipe",
"typeb": "A B type",
"jetsons": [],
"data": [
"https://myurl.com/api/data/2/",
],
"created": "2014-12-15T12:31:42.547000Z",
"edited": "2017-04-19T10:56:06.685592Z",
},
I need to parse this result and save typea and typeb into the database, I'm kind of confused on how to do this.
I mean, there is the JSONField on Django, but I don't think that will work for me, since I need to save some specific nested string of the json dict.
Any example or idea on how to achieve this?
I mean, my confusion is on how to parse this and "extract" the data I need for my specific fields.
Thank You
You can always do an import json and use json.load(json_file_handle) to create a dictionary and extract the values you need. All you need is to open the .json file (you can use with open("file.json", "r") as json_file_handle) and load the data.

Gatling JSON Feeder Unique POST Bodies

I have a JSON file that contains a JSON Array
test.json
[
{ "Name": "Bob" },
{ "Age": "37" },
{ "DOB": "12/01/1985"}
]
I would like to test each respective element in the JSON array against an endpoint to observe the performance of the system against unique payloads
currently I have
testService.scala
val payload = jsonFile("test.json").circular
val httpProtocol = http
.baseURL("http://test.com")
.headers(Map("Content-Type" -> "application/json"))
val scn = scenario("Test Service")
.feed(payload)
.exec(http("test_request")
.post("/v1/test")
.queryParam("key", "123")
.body()
I am not able to pass each respective child from the payload in the .body() as a JSON
The Gatling Docs say that the JSON Feeder loads the each element of the Array into a record collection
https://gatling.io/docs/2.3/session/feeder/
i.e:
record1: Map("id" -> 19434, "foo" -> 1)
record2: Map("id" -> 19435, "foo" -> 2)
and set the body to .body(StringBody("""[{"id": ${id}}]"""))
The issue is I have different keys (Name,Age,DOB) and I'd like each one to be a different request sent.
.body(StringBody("""[{"KEY_NAME_HERE": ${KEY_NAME_HERE}}]"""))
How do I achieve this?
This is how i am doing:-
company_users.json.json
[
{
"env":"dev",
"userName": "a#test.com",
"password": "Qwerty!12345678"
},
{
"env":"sit",
"userName": "b#test.com",
"password": "Qwerty!12345678"
},
{
"env":"uat",
"userName": "c#test.com",
"password": "Qwerty!12345678"
},
{
"env":"prod",
"userName": "d#test.com",
"password": "Qwerty!12345678"
}
]
Working Code Snippet:
val jsonFileFeederCompany = jsonFile("data/company_users.json").circular
val get_company_user_token = http("Get Company Tokens")
.post(gwt_token_url)
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.body(StringBody(
"""{
"env": "${env}",
"userName": "${userName}",
"password": "${password}"
}"""
)).asJson
.check(status.is(200))
.check(jsonPath("$.jwtToken").saveAs("jwtToken"))
val getCompanyUsersGwtToken = scenario("Create Company GWT token Scenario")
.feed(GetTokenRequest.jsonFileFeederCompany)
.exec(GetTokenRequest.get_company_user_token).exitHereIfFailed
This will read each array[position] from json and replace the values in request, to fetch security tokens from different env.
Hope this helps.
Regards,
Vikram Pathania
In your case JSONs from that array are loaded one by one, and since each first level key from that JSON will be saved as session attribute then users in your simulation end up with just 1 of 3 attributes depending which JSON was used. This way you can't (or to be precise can't easily) build body string. In that simple case it would be better to have JSONs with same fields, so you can rely on them when building request payload. Fe. you can place payload key and value in separate fields:
[
{
"key":"Name",
"value":"Bob"
},
{
"key":"Age",
"value":"37"
},
{
"key":"DOB",
"value":"12/01/1985"
},
]
This way for each user in simulation you will have two attributes key and value so you will be able to construct payload like:
.body(StringBody("""{"${key}": "${value}"}"""))
Of course this will work only in that simple case you described and with string-only values in JSONs. If your final goal is to make something more complex please provide real-life example.

Process a list of map to get a value of a key in the map

I have a list of map (parsed from json output of a rest request) like
[[Mobile:9876543210, Name:ABCD], [Mobile:8765432109, Name:EFGH], [Mobile:7654321098, Name:IJKL], [Mobile:6543210987, Name:MNOP]]
Original JSON was like
{
"data": [{
"Name": "ABCD",
"Mobile": "9876543210"
},
{
"Name": "EFGH",
"Mobile": "8765432109"
},
{
"Name": "IJKL",
"Mobile": "7654321098"
},
{
"Name": "MNOP",
"Mobile": "6543210987"
}
]
}
I want to get the mobile value from the name
Tried some things but just not working out.
Trying this in JMETER JSR223 post processor using Groovy.
You should be able to get the Mobile based on Name.
Below code fetches the Mobile 8765432109 when Name is EFGH from the OP's data. Similarly you can change the value of Name to get the right Mibile.
//Pass jsonString value to below parseText method
def json = new groovy.json.JsonSlurper().parseText(jsonString)
def result = json.data.find { it.Name == 'EFGH' }.Mobile
println result
You can quickly try online Demo
Here is an example Groovy code to fetch Name:Mobile pairs from the original JSON response (use the code in the JSR223 PostProcessor)
def json = new groovy.json.JsonSlurper().parse(prev.getResponseData())
json.data.each {entry ->
entry.each {k, v -> log.info("${k}:${v}")}
}
Demo:
References:
Groovy: Parsing and producing JSON
Groovy Is the New Black

How to add "data" and "paging" section on JSON marshalling

I know i can customize the JSON response registering JSON marshallers to Domain entities, even i can create profiles with names for different responses.
This is done filling an array that later will be marshalled like:
JSON.registerObjectMarshaller(myDomain) {
def returnArray = [:]
returnArray['id'] = it.id
returnArray['name'] = it.name
returnArray['price'] = it.price
return returnArray
}
What i want is to alter the way it gets marshalled to have two sections like
{
"paging": {
"total": 100
},
"data": [
{
"id": 1,
"description": "description 1",
}
},
...
]
}
I assume i have to implemetn a custom JSON Marshaller but i don't know how to use it for a specific response instead of wide application.
EDIT: I assume i'll need a custom RENDERER apart from the marshaller. Is this one that i don't know how to use for specific response.
What about a simple:
def json = new JSON([ paging: [ total: myArray.totalCount ], data: myArray ])
Your domain objects will be converted with the marshaller you have set up while your paging data will simply be transformed into JSON.

Populate model(database) with json data in django

I read about de/serializers but i couldn't find my way here. I have two apps, one where i store my data(scraped data) and another where i use the current/new data to display. I have identical models in these two apps. So i converted model of say app A to json and now i want to populate model of app B with that json . How might it be done? I didn't like to use django REST framework though.
so i did python manage.py dumpdata app_name > somefile.json
how do i populate fields of model B with the contents of somefile.json?
You can use model serializers. Lets say you have a model MyModel, create a serailizer for this model by,
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
You will have to create a list with each element in the list as a dictionary of MyModel instance data. JSON data in python is basically a dictionary. So each element in your list will be dictionary (JSON data) for each unique instance of your model.
The list might look like:
[
{
"pk": "1",
"field_1": "data_1",
"field_2": "data_2",
.....
},
{
"pk": "2",
"field_1": "data_1",
"field_2": "data_2",
.....
},
...
]
Now pass the list with json data for MyModel to the serializer. If the json data is valid the serializer will deserialize the data into MyModel instances. Then you can simply save them.
serializer = MyModelSerializer(data=json_data, many=True)
if serializer.is_valid():
serializer.save() # `.save()` will be called on each deserialized instance