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

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
}

Related

How do I add the `fields` array parameter when making requests to Patreon API using Postman?

I'm currently learning how to use the Patreon API. Before I integrate it into my site, I want to test the endpoints using POSTMAN. For example, I want to test the /campaign endpoint based on this documentation.
However, I'm confused how to set the parameter
fields[campaign]=created_at,creation_name
I put it in the body > x-www-form-urlencoded but it's not getting displayed in the atributes.
What is the correct way to set it?
Here is my screenshot of Postman:
Based on the documentation, the attributes in the response should have this information:
{
"data":
{
"attributes": {
"created_at": "2018-04-01T15:27:11+00:00",
"creation_name": "online communities",
"discord_server_id": "1234567890",
"image_small_url": "https://example.url",
"image_url": "https://example.url",
"is_charged_immediately": false,
"is_monthly": true,
"main_video_embed": null,
"main_video_url": null,
"one_liner": null,
"patron_count": 1000,
"pay_per_name": "month",
"pledge_url": "/bePatron?c=12345",
"published_at": "2018-04-01T18:15:34+00:00",
"summary": "The most creator-first API",
"thanks_embed": "",
"thanks_msg": null,
"thanks_video_url": null,
},
"id": "12345",
"type": "campaign"
},
From the API documentation
GET /api/oauth2/v2/campaigns/{campaign_id}
[ and ] needs to URL encode
Fields for each include must be explicitly requested i.e. fields[campaign]=created_at,creation_name but url encode the brackets i.e.fields%5Bcampaign%5D=created_at,creation_name
So you needs to change the Query Params KEY but
VALUE keep the same format field , field
From
fields[Bcampaign]
To
fields%5Bcampaign%5D

Django: outputting JSON, not OrderedDict

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.

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.

getting high resolution photos that were posted on a page wall/feed

I'm getting my page wall with the open graph.
And when someone posted a photo, I get it on the JSON
{
"id": "27888702146_10150369820322147",
"from": {
"name": "brocoli",
"category": "Record label",
"id": "27888702146"
},
"message": "Vincent Epplay / David Fenech / Jac Berrocal \u00e0 Beaubourg ce soir, 19h, gratos.",
"picture": "http://photos-f.ak.fbcdn.net/hphotos-ak-snc7/305819_10150369820292147_27888702146_8255527_583491475_s.jpg",
"link": "https://www.facebook.com/photo.php?fbid=10150369820292147&set=a.386279807146.165840.27888702146&type=1",
"icon": "http://static.ak.fbcdn.net/rsrc.php/v1/yz/r/StEh3RhPvjk.gif",
"type": "photo",
"object_id": "10150369820292147",
"created_time": "2011-10-16T08:22:21+0000",
"updated_time": "2011-10-16T08:22:21+0000",
"likes": {
"data": [
{
"name": "brocoli",
"category": "Record label",
"id": "27888702146"
},
{
"name": "Agathe Morier",
"id": "601668526"
}
],
"count": 2
},
"comments": {
"count": 0
},
"is_published": true
}
The problem is that the picture link is a low resolution copy of the picture.
How can I get the URL of the full picture ?
Thanks!!
Best
Geoffroy
You can get different version of the photo by querying Graph API with its object_id (not photo post_id which is id in results you provided).
Once you'll request the photo by object id you'll get array of images with URLs and dimensions:
http://graph.facebook.com/10150369820292147?fields=images
If you're attempting to access posts on a Facebook Page (such as for a company) instead of typical user profile, you firstly need to fetch the feed like this:
https://graph.facebook.com/v15.0/YOUR_PAGE_ID_HERE/feed?fields=attachments&access_token=...
And then access data[0].attachments.data[0].subattachments.data[0].target.id to get the object ID (or "target ID" in this case) which you can then use to perform an additional query to obtain the higher resolution image. Increment the numbers to get additional posts and images inside each post.
All you need to do is :
http://graph.facebook.com/me?fields=picture.height(961)
// replace 961 with your required height which u want
You can do this from the main posts list now using
/v2.3/105753476132681/posts?limit=5&fields=likes.summary(true),comments.summary(true), attachments
If attachments doesn't work, try full_picture - but that just gave the 100x100 image for me as well.
Attachments returns a data hash with a 640x480 version of the image at least (not sure what my orig. photo size was)
Use this Code. Its Work for me and get Clear Image
String PICTURE_URL;
String getPicture = hashMap.get("picture");
if (getPicture.contains("_t.")) {
PICTURE_URL = getPicture.replaceAll("_t.", "_n.");
} else if (getPicture.contains("_a.")) {
PICTURE_URL = getPicture.replaceAll("_a.", "_n.");
} else if (getPicture.contains("_s.")) {
PICTURE_URL = getPicture.replaceAll("_s.", "_n.");
} else if (getPicture.contains("_q.")) {
PICTURE_URL = getPicture.replaceAll("_q.", "_n.");
}
url=new URL(PICTURE_URL);
Bitmap bitmap=BitmapFactory.decodeStream(url.openConnection().getInputStream());
((ImageView)view.findViewById(R.id.imageView_FullImage)).setImageBitmap(bitmap);
Though requesting a photo by its object_id will return an array of images with different dimensions, in some cases this approach would require an additional call to the Facebook API.
A simpler approach is to add full_picture to your list of parameters, which will extract the highest resolution image associated with the post.
/v2.2/6275848869/posts?fields=full_picture
For example, if you want to extract all the posts from a Facebook page in the past X days, with the object_id approach you'd need to call the API 3 times:
To get the page info.
To extract the list of posts and obtain the object_id for each post.
For each object_id, to retrieve the list of higher resolution images.

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.