Pass information from javascript to django app and back - javascript

So I'm trying to basically set up a webpage where a user chooses an id, the webpage then sends the id information to python, where python uses the id to query a database, and then returns the result to the webpage for display.
I'm not quite sure how to do this. I know how to use an ajax call to call the data generated by python, but I'm unsure of how to communicate the initial id information to the django app. Is it possible to say, query a url like ./app/id (IE /app/8), and then use the url information to give python the info? How would I go about editing urls.py and views.py to do that?
Thanks,

You're talking about AJAX. AJAX always requires 3 pieces (technically, just two: Javascript does double-duty).
Client (Javascript in this case) makes request
Server (Django view in this case) handles request and returns response
Client (again, Javascript) receives response and does something with it
You haven't specified a preferred framework, but you'd be insane to do AJAX without a Javascript framework of some sort, so I'm going to pick jQuery for you. The code can pretty easily be adapted to any Javascript framework:
$.getJSON('/url/to/ajax/view/', {foo: 'bar'}, function(data, jqXHR){
// do something with response
});
I'm using $.getJSON, which is a jQuery convenience method that sends a GET request to a URL and automatically parses the response as JSON, turning it into a Javascript object passed as data here. The first parameter is the URL the request will be sent to (more on that in a bit), the second parameter is a Javascript object containing data that should be sent along with the request (it can be omitted if you don't need to send any data), and the third parameter is a callback function to handle the response from the server on success. So this simple bit of code covers parts 1 and 3 listed above.
The next part is your handler, which will of course in this case be a Django view. The only requirement for the view is that it must return a JSON response:
from django.utils import simplejson
def my_ajax_view(request):
# do something
return HttpResponse(simplejson.dumps(some_data), mimetype='application/json')
Note that this view doesn't take any arguments other than the required request. This is a bit of a philosophical choice. IMHO, in true REST fashion, data should be passed with the request, not in the URL, but others can and do disagree. The ultimate choice is up to you.
Also, note that here I've used Django's simplejson library which is optimal for common Python data structures (lists, dicts, etc.). If you want to return a Django model instance or a queryset, you should use the serializers library instead.
from django.core import serializers
...
data = serializers.serialize('json', some_instance_or_queryset)
return HttpResponse(data, mimetype='application/json')
Now that you have a view, all you need to do is wire it up into Django's urlpatterns so Django will know how to route the request.
urlpatterns += patterns('',
(r'^/url/to/ajax/view/$', 'myapp.views.my_ajax_view'),
)
This is where that philosophical difference comes in. If you choose to pass data through the URL itself, you'll need to capture it in the urlpattern:
(r'^/url/to/ajax/view/(?P<some_data>[\w-]+)/$, 'myapp.views.my_ajax_view'),
Then, modify your view to accept it as an argument:
def my_ajax_view(request, some_data):
And finally, modify the Javascript AJAX method to include it in the URL:
$.getJSON('/url/to/ajax/view/'+some_data+'/', function(data, jqXHR){
If you go the route of passing the data with the request, then you need to take care to retreive it properly in the view:
def my_ajax_view(request):
some_data = request.GET.get('some_data')
if some_data is None:
return HttpResponseBadRequest()
That should give you enough to take on just about any AJAX functionality with Django. Anything else is all about how your view retrieves the data (creates it manually, queries the database, etc.) and how your Javascript callback method handles the JSON response. A few tips on that:
The data object will generally be a list, even if only one item is included. If you know there's only one item, you can just use data[0]. Otherwise, use a for loop to access each item:
form (var i=0; i<data.length; i++) {
// do something with data[i]
}
If data or data[i] is an object (AKA dictionary, hash, keyed-array, etc.), you can access the values for the keys by treating the keys as attributes, i.e.:
data[i].some_key
When dealing with JSON responses and AJAX in general, it's usually best to try it directly in a browser first so you can view the exact response and/or verify the structure of the response. To view JSON responses in your browser, you'll most likely need an exstention. JSONView (available for both Firefox and Chrome) will enable it to understand JSON and display it like a webpage. If the request is a GET, you can pass data to the URL in normal GET fashion using a querystring, i.e. http://mydomain.com/url/to/ajax/view/?some_data=foo. If it's a POST, you'll need some sort of REST test client. RESTClient is a good addon for Firefox. For Chrome you can try Postman. These are also great for learning 3rd-party APIs from Twitter, Facebook, etc.

Yes, it is possible. If you pass the id as a parameter to the view you will use inside your app, like:
def example_view (request,id)
and in urls.py, you can use something like this:
url(r'^example_view/(?P<id>\d+)/', 'App.views.example_view').
The id in the url /example_view_template/8 will get access to the result using the id which is related to the number 8. Like the 8th record of a specific table in your database, for example.

About how to capture info from ajax request/urls, Usually you can do that as in a normal django requests, check url dispatcher docs and read about django views from official docs.
About how to return response, just capture the parameters, process your request then give your response with appropriate mimitype.
Sometimes you have to serialize or convert your data to another format like json which can be processed more efficiently in a client-side/js

Related

what is the proper way to issolate fetch request in a separated filed

If i want to isolate a fetch request that returns a json in a separate file i should do?
opt 1.
Separate only the fetch request and return the response object, then in the call this function do response.json()
opt2
separate request and after run response.json() method and return the response.json from the function
Follow your second approach.
Best practice in every case to bundle your requirement into same function. So here - FETCH REQUEST, GET RESPONSE, CONVERT RESPONSE AS REQUIRED, RETURN RESPONSE must be in the same method.
For the part of the code that requires the data, it is in most cases not of interest how this data is retrieved (if it is requested from the server using fetch, using WebSocket, if it is cached in local storage, ...), so you normally don't want to return an object that is related to the type of transmission, but only the received data or a customer Result object that is not related to the API you use to request the data, but one that you define yourself.
That way you can easily change the transmission type at any time, add caching, offline functionalities, ... , and you don't need to change the parts of the code that is requesting the data.

In Javascript how do I pull mealtype from edamam nutritional API

I am trying to pull the mealtype from the following API.
https://developer.edamam.com/edamam-docs-nutrition-api
Reading the API understand that we need to use a POST request to get a response specifically for mealType data. However I am very confused on how the syntax would be written for this.
for example the user puts in lasagna and the api gives me the meal type which should be Italian.
Step 1, write a service that sends a post request when you run your script. I'm assuming here you're using node, so we'd have something like, let say APIGetter. In the api getter, you want to send out an http request.
I suggest using the request module. Now when you call this function, it'll return a json string inside a promise, containing a bunch of information. You can then deserialize it (turn it into a javascript object) using JSON.parse.
However, I don't think the API does what you think it does, it gives nutrition information given a list of ingredients. It will not categorize the food for you.

JavaScript Get Data From Other Site

I'm fairly new to JS and have a question. Would it be possible to pull data off from another website to use in your own? For example, say I have a JS web app that lets a user input their Twitter username and then the script goes to this username and looks for the follower count element and pulls that number off to display back in the web app. I'm sure there are APIs and such to do something like that specific Twitter example, but I'm getting more at the general idea of being able to access data on other sites. How can it be done? Surely there is a way if my browser can access all of that information, right? Would you have to put an invisible iFrame into the app and search through it with JS?
To put it in basic terms for a newbie, this is only possible if the website in question has an API, specifically designed to allow outside access. Sometimes they're pretty easy to understand and set up.
Accessing the content of an outside website in a way it wasn't really designed to support has happened, but it's usually what's known as "hacking". It's sometimes easy to do for very basic types of sites, but most sites that request login information forbid it. (Except through aforementioned APIs). The biggest concern is that if someone is already logged in to Twitter on their browser, an outside site of questionable origin could automatically post bad things to your account while you're not even apparently visiting Twitter.
Yes, it's possible.
The best approach is to use ajax (Asynchronous JavaScript and XML) with jsonp (Javascript Object Notation with Padding) datatype.
To use this method the server you are going to connect should be expecting the request so it can response with jsonp (it's just a json data wrapped by a callback function you defined when you make the request).
The process:
1) Your code make an ajax request to the other server adding a callback function to the url. It's very commom to use "callback" param name, but the server can define the variable name it prefers.
http://other-server-url.com/?callback=myFunction
A good and easy approach here is to use jQuery. If you define dataType:"jsonp" in your ajax call, jQuery handles the process of appending the callback and execute the right function when you get the response. It's a good idea to take a look at jQuery's ajax docs and read a little about jsonp cross domain requests.
$.ajax({
type: "POST",
dataType:"jsonp",
url: "http://other-server.com/",
data: { name: "John", location: "Boston" }
}).done(function( msg ) { // this function will be executed when you get the response
alert( "Data Saved: " + msg );
});
this jQuery method only works if the param name is callback. If it isn't, you should handle by your own, or take a deeper look at documentation to know how to do it with jQuery.
2) The server should be waiting for these "callback" param and response your request with a jsonp data format. It's just json data format wrapped by the function you passed as the callback. Like this:
myFunction({ json-data });
3) When you get the response, the myFunction function will be executed automatically, with the json data as the parameter:
function myFunction(myData) {
console.log(myData); // this will log the data on the browser console
}
I hope I have helped. Good coding.

json object directly from my view HTML

i'm using phonegap in order to make an application, then i'm using CodeIgniter as an API.
To get the data, i'm using a simple $.post from jQuery to a REST URL in CodeIgniter.
$.post(DIR+trad+"/format/json", function(data){
traducciones = jQuery.parseJSON(data);
}, json);
Based upon this, i got 2 questions, because i don't know if i should do it in different post methods.
The first question is, how do i get the data in json format?
The second question is, is there any way to call the json object directly from my view (HTML) ? or i need to do it using jquery or javascript?
how do i get the data in json format?
Searching for codeigniter+json gives me Output Class which has this example:
$this->output
->set_content_type('application/json')
->set_output(json_encode(array('foo' => 'bar')));
is there any way to call the json object directly from my view (HTML)?
Generally speaking, if you are generating the JSON yourself and you want to use it in HTML, then you will just skip generating JSON and use the data directly.
Generating JSON from a view only really becomes useful if you want to make the raw data available over a network.
If you want to fetch the data over HTTP for your view, then that is a job for the Model. See How to send a GET request from PHP?. This is useful if you have two different applications. One providing a web service for the data and one providing the user facing application.
If you want to update the page with new data after it has loaded, then this is a good usecase for JSON, but you can only do that with JavaScript (or another client side programming language).
If you want to using JSON as response format, just do like
$.post(url, {
"dataType" : "json",
"success" : function(response) {
// process your response here, it will be treated as JSON object
}
});

Can Django/Javascript handle conditional "Ajax" responses to HTTP POST requests?

How do I design a Django/Javascript application to provide for conditional Ajax responses to conventional HTTP requests?
On the server, I have a custom-built Form object. When the browser POSTS the form's data, the server checks the submitted data against existing data and rules (eg, if the form adds some entity to a database, does that entity already exist in the database?). If the data passes, the server saves, generates an ID number and adds it to the form's data, and passes the form and data back to the browser.
if request.method == 'POST':
formClass = form_code.getCustomForm()
thisForm = formClass(data=request.POST)
if thisForm.isvalid():
saveCheck = thisForm.saveData()
t = loader.get_template("CustomerForm.html")
c = Context({ 'expectedFormObj': thisForm })
(Note that my custom logic checking is in saveData() and is separate from the html validation done by isvalid().)
So far, standard Django (I hope). But if the data doesn't pass, I want to send a message to the browser. I suppose saveData() could put the message in an attribute of the form, and the template could check for that attribute, embed its data as javascript variable and include a javascript function to display the message. But passing all that form html back, just to add one message, seems inelegant (as does the standard Django form submission process, but never mind). In that case I'd like to just pass back the message.
Now I suppose I could tie a Javascript function to the html form's onsubmit event, and have that issue an XMLHttpRequest, and have the server respond to that based on the output of the saveData() call. But then the browser has two requests to the server outstanding (POST and XHR). Maybe a successful saveData() would rewrite the whole page and erase any potential for conflict. But I'd also have to get the server to sequence its response to the XHR to follow the response to the POST, and figure out how to communicate the saveData outcome to the response to the XHR. I suppose that is doable, even without the thread programming I don't know, but it seems messy.
I speculate that I might use javascript to make the browser's response conditional to something in the response to the POST request (either rewrite the whole page, or just display a message). But I suspect that the page's javascript hands control over the browser with the POST request, and that any response to the POST would just rewrite the page.
So can I design a process to pass back the whole form only if the server-side saveData() works, and a message that is displayed without rewriting the entire form if saveData() doesn't? If so, how?
Although you can arrange for your views to examine the request data to decide if the response should be an AJAXish or plain HTML, I don't really recommend it. Put AJAX request handlers in a separate URL structure, for instance all your regular html views have urls like /foo/bar and a corresponding api call for the same info would be /ajax/foo/bar.
Since most views will examine the request data, then do some processing, then create a python dictionary and pass that to the template engine, you can factor out the common parts to make this a little easier. the first few steps could be a generic sort of function that just returns the python dictionary, and then actual responses are composed by wrapping the handler functions in a template renderer or json encoder.
My usual workflow is to initially assume that the client has no javascript, (which is still a valid assumption; many mobile browsers have no JS) and implement the app as static GET and POST handlers. From there I start looking for the places where my app can benefit from a little client side scripting. For instance I'll usually redesign the forms to submit via AJAX type calls without reloading a page. These will not send their requests to the same URL/django view as the plain html form version would, since the response needs to be a simple success message in plain text or html fragment.
Similarly, getting data from the server is also redesigned to respond with a concise JSoN document to be processed into the page on the client. This also would be a separate URL/django view as the corresponding plain html for that resource.
When dealing with AJAX, I use this:
from django.utils import simplejson
...
status = simplejson.dumps({'status': "success"})
return HttpResponse(status, mimetype="application/json")
Then, AJAX (jQuery) can do what it wants based on the return value of 'status'.
I'm not sure exactly what you want with regards to forms. If you want an easier, and better form experience, I suggest checking out uni-form. Pinax has a good implementation of this in their voting app.
FYI, this isn't an answer...but it might help you think about it a different way
Here's the problem I'm running into...Google App Engine + jQuery Ajax = 405 Method Not Allowed.
So basically I get the thing to work using the outlined code, then I can't make the AJAX request :(.

Categories