How to use Backbone collection's create method correctly - django

I found that when I use the collection.create to create a new model, backbone will send a post request, but the post data is incorrect
for example
collection.create({name:'test'})
backbone will send POST data using "{name:'test'}" as key, and "" as value,
but I want the POST data by using name as key, 'test' as value,
can anybody no how to setting it,
I use django as the server
thanks in advance

Unless you change it backbone's collections use Backbone.sync to communicate with your backend.
In the docs they say:
With the default implementation, when Backbone.sync sends up a
request to save a model, its attributes will be passed, serialized as
JSON, and sent in the HTTP body with content-type application/json
So I guess you need to do something like this in your django view
json.load(request.POST)
or use a custom sync function that does not serialize the data to json

You'll need to parse the raw post data string and parse it into a python dict.
import json
data = json.loads(request.raw_post_data)

You can also set
Backbone.emulateJSON = true;
as per http://backbonejs.org/#Sync-emulateJSON

Related

Refresh model from JSON

I have a deeply nested model with one-to-one and one-to-many relationships. Initially I retrieved this model from server using standard ember-data API.
What I need to do now is to update model (and all its relationships) from a plain JSON retrieved by an AJAX call.
I cannot use reload() method, because that would make an additional HTTP request - I already have the JSON payload, so no need for an extra HTTP request.
Is there a way to reload a model from JSON?
You can use pushPayload/push for to add new records and update the existing records in store.
To revert all old changes, You can get all the records from store by peekAll, and iterate it for hasDirtyAttributes, if its true then unload it from store. after that you can use pushPayload to update the incomind records into store.
let allRecords = this.get('store').peekAll('modelname')
let dirtiedRecords = allRecords.filterBy('hasDirtyAttributes',true);
dirtiedRecords.forEach((item) =>{
item.unloadRecord();
});
//after that you can use pushPayload the result you got it from Ajax call.
Refer:
https://emberjs.com/api/data/classes/DS.Model.html#property_hasDirtyAttributes
https://emberjs.com/api/classes/Ember.Enumerable.html#method_filterBy
https://emberjs.com/api/data/classes/DS.Store.html#method_pushPayload

Missing form data in request

I have following code
class MyClass(restful.Resource):
def get(self):
headers = {'Content-Type': 'text/html'}
return make_response(render_template('myfile.html'),200,headers)
def post(self):
session['CONSUMER_KEY']=request.form.get('consumer_key')
session['CONSUMER_SECRET']=request.form.get('consumer_secret')
render_template('myfile.html')
api.add_resource(MyClass,"/mag/",endpoint="mag")
I have written following test:
def mytest(self):
content_type={"Content-Type": "application / x - www - form - urlencoded","Content-Disposition": "form-data"}
response = self.client.post(
api.url_for(MyClass), data = json.dumps({'consumer_key':'testconsumerkey',
'consumer_secret':'testconsumersecret'}),
headers=content_type
)
The issue is form data is blank and thats the values are not getting set in session. When i debug i see that request.data is populated but request.form is an empty dictionary. Can someone suggest how I can send form data in a post request from a test
EDIT: Environment details
Python 2.7, Flask web framework, self.client is . I am using flask.ext.testing
You seem to be confused as to what the expected format for the post body should be. Should it be JSON data (which is what you send in the test case), or should it be in the application/x-www-form-urlencoded format (which is what you claim to send in the test case, and what the endpoint will read)?
If you wish to receive JSON data, you'll need to change the endpoint to read the data from request.get_json(). You'll also need to use application/json as the Content-Type header in the test case.
If you wish to receive urlencoded post data, then just simplify the test case by removing the Content-Type header and the json.dumps. Just pass the data dict to the data argument.

How to send a parameter which is dictionary in Postman

I have just started using Postman for testing my API.
I am able to send list of request parameters, but could not figure out how will I send a parameter which is a dictionary,
say my request has two different parameters, first is property, and the structure of property is something like "ptype":"residential","mtype":"requirement","dtype":"sale","category":"multistoryapt","city":"Gurgaon,Mumbai"
How can I send these parameters together ?
I have explored on internet and there are ways of sending an array but not a dictionary.
Am I missing something ?
You could send data as raw body with the Content-Type application/json, this way it's up to you how the data is structured.
If you want to send it in the application/json format then the body should look like this:
{
"key1":"value1",
"key2":"value2"
}
For a comprehensive resource on how to serialise JSON go to http://www.newtonsoft.com/json/help/html/SerializingCollections.htm
If for some reason you cannot send it with json, here is how we send dictionaries in the form:
object[ptype], object[mtype], object[dtype], object[category], object[city]
You can do it with this:
POST Request in Postman:
Content-Type: Json/Application
{
"IsManual":true,
"platform":"IOS",
"barcodeList":{"1":"DSSDsdsdsas","2":"DSSDsdsdsas"},
"Client":"Cliente1",
"ScanDate":"2018-10-16T17:03:02.2347052-03:00"
}
I cam across this topic as I have a parameter
public Dictionary<string, string> Customer { get; set; }
for my REST API and I wanted to test it with Postman. Unfortunately I didn't find any quick help for how to send a Dictionary using Postman. After trying around some combinations this is what worked for me
Customer[0].Key:name
Customer[0].Value:Testname
Match the name of your dictionary and Request body dictionary name.
Suppose ,
Dictionary<string,string> randomName = new Dictionary<string,string(){{"key1","value1"} ,{"key2","value2"}};
so , your request for PostMan should be:
{
"randomName " : { "key1":"value1", "key2":"value2"}
}

How to send data as key - value pairs instead of string via POST using XHR

I'm creating two POST calls. One using a django form and one using angular js via a resource xhr.
The angular setup looks like this:
myModule.factory('gridData', function($resource) {
//define resource class
var root = {{ root.pk }};
var csrf = '{{ csrf_token }}';
return $resource('{% url getJSON4SlickGrid root.pk %}:wpID/', {wpID:'#id'},{
get: {method:'GET', params:{}, isArray:true},
update:{method:'POST', headers: {'X-CSRFToken' : csrf }}
});
});
With creating an xhr post request as such:
item.$update();
This post request is send to the server as expected, but when I want to access the QueryDict I cannot access the data passed using:
name = request.POST.get('name', None)
name is always None like this.
The issue behind this is that the QueryDict object is getting parsed quite strange.
print request.POST
<QueryDict: {u'{"name":"name update","schedule":0"}':[u'']}>
Whereas I would have expected this result, which I got when I send the data via a "normal" Post request:
<QueryDict: {u'name': [u'name update'], u'schedule': [u'0']}>
So it seems to be that Django receives something in the POST request which instructs Django to parse the parameters into one string. Any idea how to circumvent this?
Update:
I found this discussion where they say that the issue is if you provide any content type other than MULTIPART_CONTENT the parameters will be parsed into one string. I checked the content-type send with the POST request and it is really set to 'CONTENT_TYPE': 'application/json;charset=UTF-8'. Thus this is likely the issue. Therefore my question is: How can I set the CONTENT_TYPE for a xhr post request created using angular.js resources to MULTIPART_CONTENT?
you could either:
fiddle with the client to send data instead of json
use json.loads(request.raw_post_data).get('name', None) (django < 1.4)
use json.loads(request.body).get('name', None) (django >= 1.4)
The Angular documentation talks about transforming requests and responses
To override these transformation locally, specify transform functions as transformRequest and/or transformResponse properties of the config object. To globally override the default transforms, override the $httpProvider.defaults.transformRequest and $httpProvider.defaults.transformResponse properties of the $httpProvider.
you can find an example here as was previously pointed at.

Access raw_post_data in django test client

The title pretty much says it all: I use raw_post_data in a couple of views, and thus I need the test client to properly grant access to it.
I have copied the raw_post_data string, from a mock request, passed it to json.loads(), and then used the resulting dict as the POST data for the test client. Then, I set the content type to "application/json" - this causes raw_post_data to appear, but it is not the same raw_post_data as the mock request.
When you change the content type in the test client, the data parameter is not parsed as a dictionary anymore but sent directly. Try copyin your JSON string directly as the data parameter to your post request, you should receive it in raw_post_data in your application.
Just need to follow the steps as below:
1. set the data attribute to your string.
2. then set the content_type attribute to application/octet-stream.
payload = {'k1':'v1'}
data = json.dumps(payload)
response = self.client.post(url, data=data, content_type='application/octet-stream', **self.auth_headers)