Django: outputting JSON, not OrderedDict - django

I have a strange problem.
I have an API built with the Django REST framework.
I'm making a call and getting the following JSON back:
{
"success": true,
"result": {
"user_type": "ta",
"email": "myemail#gmail.com",
"first_name": "John",
"last_name": "Smith",
"mobile_phone": "555-555-5555",
"id": "0f165a85-2da6-4dcb-97cb-bf04900a942b"
}
}
I've tried to add a logging middleware when I'm trying to get the same output from response.data and writing int into a text field in my database.
For the very same request response.data is this: (and this gets written into my db, instead of the desired JSON string from above):
{'success': True, 'result': OrderedDict([('user_type', 'ta'), ('email', 'myemail#gmail.com'), ('first_name', 'John'), ('last_name', 'Smith'), ('mobile_phone', '555-555-5555'), ('id', UUID('0f165a85-2da6-4dcb-97cb-bf04900a942b'))])}
Why is that? How can I get get rid of that OrderedDict and get a perfect JSON string from response.data?
Please note: json.dumps doesn't work. I'm getting TypeError: Object of type 'UUID' is not JSON serializable. My entire ID system in the models is based on UUIDs. However, my Django REST framework is capable of serializing it just fine in the above example... how is that done?

You are hitting this problem because you're trying to dump the internal representation using json.dumps, which doesn't know how to handle UUID objects.
I can see two options - one, teach dumps how to serialize a UUID. This can be done by subclassing JSONDecoder, e.g. this SO answer.
However, DRF already knows how to serialize these fields. Poking around in the debugger, it looks like the response text is stashed in response.rendered_content. I'd check if that's populated by the time your middleware is run.

json.dumps(log_data, indent=2)
this can format your dict to the str you want.
eg:
# save log_data in some way
log_data = {
"success": True,
"result": {
"user_type": "ta",
"email": "myemail#gmail.com",
"first_name": "John",
"last_name": "Smith",
"mobile_phone": "555-555-5555",
"id": "0f165a85-2da6-4dcb-97cb-bf04900a942b"
}
}
logger.info(json.dumps(log_data, indent=2))
print(json.dumps(log_data, indent=2), type(json.dumps(log_data, indent=2)))
logger save to django.log like:

I managed to find this posted solution.
https://arthurpemberton.com/2015/04/fixing-uuid-is-not-json-serializable
I added the code to my models and now I do not get TypeError: Object of type 'UUID' is not JSON serializable when I serialize my UUID fields. This allowed me to call json.dumps on my response.data and serialize it to text perfectly.

Related

How to convert array of object(hasMany relationship data) to array of id?

I wanted to get data and show it in UI. Here's how i write to get the "movies" data.
let movies= yield this.store.findAll('movie');
And I log the "movies". As the picture below shows that there's no data for "photos".
Here's the network:
I'm getting data back from hasura like this:
{
"data": {
"movies": [
{
"id": "584db434-5caa-475e-b3ec-e98e742f0030",
"movieid": "abc123",
"description": "Penquins dancing in antactica",
"photos": [
{
"id": "c4d2833a-4896-42b0-ae8b-0ab9fe71d1d4"
},
{
"id": "e04697e3-21fe-4f0e-8012-443f26293340"
}
]
}
]
}
}
But Ember.js can't read and render the relationship data (photos). Is it the "photos" data should be like this?
"photos": [c4d2833a-4896-42b0-ae8b-0ab9fe71d1d4, e04697e3-21fe-4f0e-8012-443f26293340]
How can I convert it in Ember? or in Hasura?
Thanks for updating your question!
Since you're using ember-data, you'll need a custom adapter and serializer to form your data into the format that ember-data is expecting (since there are infinite numbers of ways APIs decide how to structure data).
More information on that can be found here:
https://guides.emberjs.com/release/models/customizing-adapters/
and here: https://guides.emberjs.com/release/models/customizing-serializers/
Your data is fairly well structured already, so conversion should hopefully go well. Comment back if you have issues <3

How to filter based on a nested Django JSONField?

I have a json field for a model in my Django app that typically has nested json in it. I read that to filter on a JSONfield, you would use contains on the filter for whatever value you are looking for, but I'm not getting any results back even though I know the value does exist in the JSONField. Is there an extra step I need to use for nested json in a json field?
JSON Field "Field name is Content "
"content": {
"documents": [
{
"id": "378",
"name": "Test.pdf",
"mediaFile": "http://localhost:8000/media/file.pdf"
}
]
}
Query:
document_modules =
WMDocumentModule.objects.filter(content__documents__contains={'id': "378"})
>>> document_modules: <QuerySet []>

How to update object with an image field - Django Rest Framework

I have a model called ProductImage that contains a few fields and an Django ImageField. In this case I already have the object created, and I want to update the featured boolean in the object.
Problem is that when I do a $http.put() (Using AngularJS) I get an error returned saying:
The submitted data was not a file. Check the encoding type on the form.
My REST API Object looks like this on the GET request:
{
"id": 15,
"image": "http://127.0.0.1:8000/media/products/photo_1_5.JPG",
"alt": "HelloWorld",
"featured": false,
"product": 1
}
The HTTP PUT request I send looks like this: (Notice featured has been changed to true)
{
"id": 15,
"image": "http://127.0.0.1:8000/media/products/photo_1_5.JPG",
"alt": "HelloWorld",
"featured": true,
"product": 1
}
So... How do I update my object without having to re-submit/re-upload the image file?
If you use PUT to update an object you have to send a full instance. So in your case you have to send a image file for image not an url to the image.
The easiest solution is probably to use PATCH instead of PUT. Then you can do a partial update and send only the updated fields.
{
"featured": true
}

Passing JSON data from response to request in Django

I have a Django (1.8.3) view that:
Makes a GET request to Server A (jetty), which returns JSON data in the body of the response. Then,
Makes a POST to Server B (node.js), passing the JSON data recieved from Server A in the body of the request.
The JSON data is structured like:
{
name: "foo",
details: {
"date": "today",
"isCool": "no",
},
stuff: [
{
"id": "1234",
"rating": "5",
}, {
"id": "5678",
"rating": "1",
},
]
}
But I can't figure out how to get the JSON from Server A's response into the request to Server B in my Django view. If I do this:
jetty_response = requests.request(method='GET', url=jetty_url)
node_response = requests.request(method="POST", url=node_url,
data=jetty_response.json())
I get the JSON object in Server B, but it looks like this:
{
name: "foo",
details: [ "date", "isCool"],
stuff: [ "id", "rating", "id", "rating"]
i.e. the name property is correct, but the details dict is instead received as the keyset of the original dict, and the stuff list is received as a flat array of the keysets in all objects in the original dict.
If I instead do this in django:
node_response = requests.request(method="POST", url=node_url,
data=json.dumps(jetty_response.json()))
I get an empty object in node, and same goes if I do simply:
data=jetty_response.content
How do I make this request??
Figured it out myself.
As is usually the case, the simplest answer:
node_response = requests.request(method="POST", url=node_url,
data=jetty_response.content)
worked fine once I took a closer look at my log and realized my POSTs were bouncing back 413, and then adjusted the size limit on my bodyParser in express.

real-time update page feed

here I am for real update "page", add fields to status to receive the "status" of
pages, I try to add as "link" fields to receive the subscription works but I do
not receive notification when I publish a link, it's really difficult to have
correct information
{
"object": "user",
"callback_url": "http://*/fbcallback.php",
"fields": [
"feed",
"link",
"status"
],
"active": true
}
http://bugs.developers.facebook.net/show_bug.cgi?id=18048#c40
As per the documentation at https://developers.facebook.com/docs/reference/api/realtime/ :
To setup a subscription, send a POST with the following parameters
It seems like you're posting a JSON object while you should do is a normal post with these variables (as if you're doing a with action="post").
Note, by the way, that the fields parameter needs to have a CSV value, so that would be "feed,link,status", and that there's no 'active' attribute.