Data manipulation in Django json response - python

I want to iterate over device object and add a comparison.
The json looks like below. I want to compare let's say if status is 1 to add new field for each device "status" : "available" else "status" : "Occuppied". How can i manipulate json like that?
View:
from django.core import serializers
def ApplicationDetail(request, application_id, cat):
device = Device.objects.all().filter(category=cat)
data = serializers.serialize('json', device)
return HttpResponse(data, content_type='application/json')
JSON:
[
{
"model":"applications.device",
"pk":"70b3d5d720040338",
"fields":{
"icon_name":"amr.jpg",
"application_id":13,
"status":1
}
},
{
"model":"applications.device",
"pk":"70b3d5d72004034c",
"fields":{
"icon_name":"amr.jpg",
"application_id":13,
"status":0
}
}
]

Django's built in serializers are very basic, if you are building some sort of JSON API I'd strongly recommend to check out Django REST Framework (https://www.django-rest-framework.org/). Which allows you to build custom serializers.
To answer you question, it's probably easiest to use the 'python' serializer, manipulate the data and then return a JsonResponse, something like this:
from django.http import JsonResponse
...
data = serializers.serialize('python', device)
for row in data:
row['fields']['status'] = 'available' if row['fields']['status'] else 'occupied'
return JsonResponse(data, safe=False)
In order to serialize objects other than dict you must set the safe parameter to False
https://docs.djangoproject.com/en/3.0/ref/request-response/#jsonresponse-objects

Related

Use existing ModelSerializer with JSONResponse

I have a Twitter authentication view that doesn't use a viewset so the auth can be handled on the backend. The view takes in the oauth_token & uses Twython to get the profile & create a Twitter model.
Currently I just return status 201 on success, but to alleviate the need for another request after creation, I'd like to return the created model. I have a TwitterSerializer already which defines the fields that I want to include, so I'd like to be able to reuse this if possible.
TwitterSerializer
class TwitterSerializer(serializers.ModelSerializer):
class Meta:
model = Twitter
fields = (
"id",
"twitter_user_id",
"screen_name",
"display_name",
"profile_image_url",
)
When I try to use this, I get the error that Instance of TwitterSerializer is not JSON serializable.
serialized = TwitterSerializer(instance=twitter)
return JsonResponse({ "created": serialized })
I could return a serialized instance of the model using serializers.serialize()
serialized = serializers.serialize('json', [twitter, ])
serialized = serialized[0]
return JsonResponse({ "created": serialized })
I could pass the fields kwarg to serialize() but I don't want to have to repeat myself if I don't have to. So would it be possible to re-use my TwitterSerializer in this case? I'm having trouble finding a direct answer since most docs assume you'll be using a ViewSet when using serializerss understandably, and this feels like an edge case. I'm open to suggestions for refactoring this approach as well!
After serialization, you can get your data using data attribute of serializer like this.
serialized = TwitterSerializer(instance=twitter)
return JsonResponse({ "created": serialized.data })
You should use Django rest Response instead of JsonResponse like this
from rest_framework response
serialized = TwitterSerializer(instance=twitter)
return response.Response({ "created": serialized.data })

Return JSON field in GAE ProtoRPC

I want to construct an arbitrary json like this and return to the user dynamically
{
"items":[
{
"available":"2",
"capacity":"2",
"name":"name2",
"entityKey":"dkfhakshdfh"
},
{
"available":"1",
"capacity":"1",
"name":"name1",
"entityKey":"dkfhaksdfef"
}
],
"kind":"theatreManagement#show",
"etag":"\"asdfasdfasfasfahih\""w
}
But there seems to be no fields to pass in the json. The fields available are like StringField, BytesField, etc.,
How to return a json object?
OpenAPI services such as those created by the Google Cloud Endpoints Framework need to specify exactly what they return. You should define a message containing fields like 'items', 'kind', 'etag', and so on.

Django Rest Framework: Custom JSON Serializer

I am struggling to figure out how to write a custom serializer in DRF to parse a complex JSON data structure that is being passed to an endpoint. The JSON looks like this:
{
"name": "new",
"site": "US",
"data": {
"settings": [],
"meta": {
"meta1":{}
}
}
}
Here is my backend code:
# views.py
class SaveData(views.APIView):
def post(self, request, *args, **kwargs):
name = request.POST.get('name')
site = request.POST.get('site')
data = request.POST.get('data')
But data always returns None. On closer inspection into the request object, the incoming JSON looks like this:
# POST attribute of request object
'name' = 'new'
'site' = 'US'
'data[settings][0] = ''
'data[meta][meta1][] = ''
Basically it looks like the nested JSON objects associated with the data key are not getting properly serialized into Python dict and list objects. I've been looking for examples of custom DRF serializers but most of the ones I've found have been for serializing Django models, but I don't need to do that. The incoming data does not directly map to my models; instead I need to do some processing before I save any of the data.
Does anyone have any advice on a custom serializer that would properly convert the data JSON into proper Python objects? I started with this but it throws an exception (When a serializer is passed a 'data' keyword argument you must call '.is_valid()' before attempting to access the serialized '.data' representation.
You should either call '.is_valid()' first, or access '.initial_data' instead.). Here is my code with the custom serializer I created:
# serializers.py
class SaveDataSerializer(serializers.Serializer):
name = serializers.CharField()
site = serializers.CharField()
data = serializers.DictField()
def create(self, validated_data):
return dict(**validated_data)
Thanks.
I was able to solve my problem by converting the JS object to JSON when passing it to $.ajax, which then DRF was able to correctly parse into Python objects. Here's a snippet of the jQuery I'm using:
$.ajax({
url: '/api/endpoint',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(ajaxData),
done: function(data) {}
...
})
Note though that jQuery will default to x-www-urlencoded as the Content-Type if you don't specify anything. Since I'm using the JSON.stringify() method to explicitly convert the ajaxData object to a JSON string the Content-Type needed to be explicitly set as well.
I got the idea from this SO answer: Convert Object to JSON string
Of course, this doesn't really answer my original question, but this is another solution that is simpler and works like I wanted. By doing this I didn't have to create any custom serializers, but I did have to modify my API view like so:
class SaveData(views.APIView):
def post(self, request, *args, **kwargs):
name = request.data.get('name')
site = request.data.get('site')
data = request.data.get('data')
After doing this the expected object types are returned
>>> type(name)
str
>>> type(site)
str
>>> type(data)
dict

Django: send json response from view to a specific template

The main requirement is to send a json object from django view to a specific template named output.html (already present in templates directory), as a part of response. Also, the json response contains model and pk attribute, I want to remove them and send only the fields json attribute.
When I try as follows :
def view_personal_details (request):
personal_detail_json = personal_details.objects.all()
personal_detail = serializers.serialize('json', personal_detail_json)
return HttpResponse (serializers.serialize('json', personal_detail_json), content_type='application/json');
I get json in a new page.
And when I try as follows :
def view_personal_details (request):
personal_detail_json = personal_details.objects.all()
personal_detail = serializers.serialize('json', personal_detail_json)
return render (request, "webFiles/output.html", {'personal_detail': personal_detail})
I have to access the data via {{ personal_detail }} in my html, and not from response.
Also, the json response is as follows :
[
{
model: "buglockerApp.personal_details",
pk: "001",
fields: {
name: "Rajiv Gupta",
email: "rajiv#247-inc.com",
doj: "2016-06-22",
dob: "2016-06-22",
address: "Bangalore",
contact: "9909999999"
}
}
]
I don't want the model and pk to be sent as the response. Only fields should be sent as a part of response to webFiles/output.html file.
Thanks in advance!!
you can do the following in python2.7
import json
from django.http import JsonResponse
def view_personal_details (request):
personal_detail = serializers.serialize('json', personal_details.objects.all())
output = [d['fields'] for d in json.loads(personal_detail)]
# return render (request, "webFiles/output.html", {'personal_detail': output})
# for ajax response
return JsonResponse({'personal_detail': output})
or you can read the following for more clarification
https://docs.djangoproject.com/en/1.10/topics/serialization/#serialization-of-natural-keys
https://github.com/django/django/blob/master/django/core/serializers/base.py#L53
The default serializers always add the model and pk so that the data can be deserialized back into objects. Either you can write a custom serializer or can simply remove the unwanted data.
personal_details = [pd['fields'] for pd in personal_details]
This should give you a new list of dicts with personal details

Django json serialize doesn't return Object

I'm trying to write an API view for my Django REST API that takes a Location object and serializers it "by hand" -- with json.dumps. Here's an example:
class LocationDetail(APIView):
def get(self, request, location_id, format=None):
l = Location.objects.get(id=location_id)
response_dict = {
"id": l.id,
"name" : l.name,
}
json_data = json.dumps(response_dict)
return Response(json_data)
this will, quite unsurprisingly, return a json object, such as this:
{"name": "Some Place", "id" : 1, ...}
This does not return a proper API response, according to https://www.hurl.it/.
But I need the API to return an Object. Here's the version where I use the built-in REST Framework's Serializer class:
serialized_location = LocationSerializer(l)
return Response(serialized_location.data)
This throws back the "proper" response, and does not cause an error in hurl.it:
Object {id: 1, name: "Some Place", …}
I'd like to figure out how to emulate the behavior of the REST serializer -- how do I get it to return an Object of json instead of just the json?
Here is the difference in images, one is clearly correct and the other just doesn't look like an API response:
REST framework serializer:
My custom json thing:
My custom json with "object" key addition:
They're weirdly different -- I want mine to be recognized as an API response too.
SOLUTION: If anyone else is interested, what you can do is just not json dump the object. Just return:
return Response(response_dict)
that simple. That will return an object appropriate for parsing.
Maybe you should just try this:
json_data = json.dumps(dict(object=response_dict))

Categories