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''


EDIT
I 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)





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



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.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Export result set on Dbeaver to CSV

Opening a url is failing in Swift