How to call Python functions from JavaScript in Django?
How to call Python functions from JavaScript in Django?
I've been struggling on this for a couple days. I've read through many posts, blogs, and watch video demo on Django projects, but nothing quite answers my problem.
I have a Django webapp that uses a Python API to connects to a third-party service to analyze text data. The user writes into a text area, presses the button, then the text is sent to the service which returns a list of JSON objects. The API call to this service is a Python function. I'm trying to use Ajax to make an async call to the Python function using the text data as a param when the button is pressed.
I'm not at this time trying to invoke my third-party service, yet. I'm just trying to see if I can get a response from Python sending input and receiving output.
Most of the examples I've found involve creating a form and submitting it so the Django framework automatically calls it's Python functions. A form is not exactly what I'm trying to build, nor am I wanting to proceed to a new page to see the results or refresh the current one.
<!-- index.html -->
<html>
<head>
<title>Test Data</title>
https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js
document.getElementById("Button").addEventListener('click', analyzeText());
function analyzeText(){
var text = document.getElementById('text-to-analyze').value;
$ajax({
type: "POST",
url: "/models.py", /* Call python function in this script */
data: {param: text}, /* Passing the text data */
success: callback
});
}
function callback(response){
console.log(response);
}
</head>
<body>
<textarea id="text-to-analyze" rows="12" cols="100"></textarea><br>
<button id="button" value="Analyze"/>
</body>
</html>
# models.py
from django.db import models
# Function I want to call from Ajax
def testcall():
return 'test successfull'
EDIT:
I almost have it working. I'm just getting syntax errors with ajax I can't figure out.
Could not parse the remainder: ' 'ajax-test-view'' from 'url 'ajax-test-view''
EDITI fixed all the syntax errors but now I'm getting 404 errors when trying to execute the target python script. I now understand how url and pathing works in Django, but using Kostadin Slavov's solution, how can I do this without routing to a specific html?
In the ajax, I'm setting the url like this:url: '{{ 'ajax-test-view' }}',
And in my python I have the url pattern set like this:path(r'^django-app/$', views.testcall, name = 'ajax-test-view'),
url: '{{ 'ajax-test-view' }}',
path(r'^django-app/$', views.testcall, name = 'ajax-test-view'),
It seems like the variable in the ajax url points to the name field in the url pattern, but that also seems to be the name of a specific html file to render(?) Or is it the name of the py function?
When I click my button the ajax sends a command to http://localhost:8000/what-ever-the-name-field-is-in-the-url-pattern
and I get a 404 from it. Is the framework trying to load a page or does it mean it can't find my python file?
Derp... It's important to know that url: '{{ 'ajax-test-view' }}',
is the url address ajax will request and Django's url dispatcher intercepts it to do something else only if the path matches perfectly.
FINAL EDIT
Got it working. A couple things I changed in Kostadin Slavov's solution:
http://localhost:8000/what-ever-the-name-field-is-in-the-url-pattern
url: '{{ 'ajax-test-view' }}',
# urls.py
urlpatterns = [
url(r'^$', views.index, name = 'index'),
path('my-ajax-test/', views.testcall),
]
<!-- index.html -->
....
var text = "test successful";
$.ajax({
type: "POST",
url: '{{ 'my-ajax-test/' }}',
data: { csrfmiddlewaretoken: '{{ csrf_token }}', text: text },
success: function callback(response){
console.log(response);
}
});
# views.py
def testcall(request):
return HttpResponse(request.POST['text'])
2 Answers
2
in the urls.py
you create an url
urls.py
url
path('my-ajax-test/', views.myajaxtestview, name='ajax-test-view'),
then your ajax should loook like
pay attention to the csrf_token
otherwise will send you an error
csrf_token
$ajax({
type: "POST",
url: '{{ url 'ajax-test-view'}}',
data: {csrfmiddlewaretoken: '{{ csrf_token }}',
text: "this is my test view"}, /* Passing the text data */
success: function(response){
alert(response);
}
});
in views.py
views.py
def myajaxtestview(request):
return HttpResponse(request.POST['text'])
Summary:
you need to create the url
in your urls.py
which leads to your views.py
then the view gets the data that you've sent in the request.POST
in the request
you have plenty of data you can find more about it here.
in your case you are more interested in request.POST
it's a python dictionary
so you pick the parametre that you have send and work with it
you may play with it like return HttpResponce('test'+ request.POST['text'])
url
urls.py
views.py
request.POST
request
request.POST
return HttpResponce('test'+ request.POST['text'])
If you want to get something from models.py
let's say you data that you sent from the js is {object_type: hammer}
models.py
{object_type: hammer}
def myajaxtestview(request):
look_for = request.POST['object_type']
#lets say you have model Items
my_items= serializers.serialize('json', Items.objects.filter(object_type=look_for))
return JsonResponse(my_items)
from django.urls import path
Figured it out. stackoverflow.com/questions/47563013/… I'm using Visual Studio python tools to build my django project and I wasn't paying attention to version numbers.
– GhostRavenstorm
Jun 29 at 20:32
ooh nice did it work?
– Kostadin Slavov
Jun 29 at 20:34
I almost have it working. I'm getting syntax errors with the ajax. See OP edit.
– GhostRavenstorm
20 hours ago
Got it working. See OP edit for what I changed:
– GhostRavenstorm
19 hours ago
What you are trying is a well known problem. When you do ajax request to the server , the server responds with some data or may be renders a template.
For this request - response cycle to work, you will have to create a mapping of the url to the controller logic. You will have to create a url and a python function mapping in urls.py.
The python function will be in views.py. Now when you request for that url with the given method(POST or GET), it will call the mapping function and return the result.
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
This makes a lot of sense, but I'm having trouble recreating it. I get an error that says 'path is undefined'. I tried importing
from django.urls import path
, but then it says it can't import path. I'm afraid I'm not that familiar with Django yet.– GhostRavenstorm
Jun 29 at 20:24