Parth Bhoiwala
Parth Bhoiwala

Reputation: 1322

Django: Unable to call python function from Javascript

I have a Django project with the following structure. My project name is SimpleWeb. I have an application named query. Now I have an HTML page which has a dropdown menu and a submit button.

Here is what I am trying to do. When the user selects an item from the dropdown and hits submit, I want to call a python function in my view.py file, do something with that item and return a list back.

The problem is that I think that my function named runQuery is not being called for some reason. Below is my code

SimpleWeb\urls.py

from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^runQuery/$', include('query.urls')),
    url(r'^$', include('query.urls')),
]

query\urls.py

from django.conf.urls import include, url
from . import views

urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^runQuery', views.runQuery, name='runQuery'),
]

view.py

from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    # this function powers the main page: 'http://127.0.0.1:8000/'
    List = ['item1','item2','item3']
    return render(request, 'query/home.html', {'list': List})


def runQuery(request):
    # this function needs to be called using $http from javascript 
    # I want to get what user submitted in $http and do something with it here
    # then return a list, below is a sample list 
    fruitList = ['apple', 'banana', 'orange']
    return HttpResponse(fruitList)

script.js

angular.module('myApp', []);
angular.module('myApp').controller('myCtrl', ['$scope', '$http', function ($scope, $http) {

$scope.submitButtonclicked = function(){
    var userInput = $scope.data.dropdown /* item that user chooses from dropdown*/

    $http({
        method: 'GET',
        url: '/runQuery',
        params: {yourChoice: userInput}
    }).then(function successCallback(response){
        console.log(response); /* When I debug in chrome browser, I see that it logs an HTML page as the response instead of fruit list */
    }, function errorCallback(response) {
        console.log("Oops, error occurred");
    });
 };
}]);

Again, I posted most of the code that I thought was relevant and might help you find a solution. My coworker told me that the way I have defined runQuery in my urls.py file could be messed up and that's why runQuery() function is not getting called properly. I don't know how to fix this. Thanks you :)

Upvotes: 0

Views: 986

Answers (2)

Carlos Perea
Carlos Perea

Reputation: 616

You're not defining the URLs correctly so the router can't find the correct method. One way you could define the URLs:

SimpleWeb\urls.py

from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
   url(r'^admin/', admin.site.urls),
   url(r'', include('query.urls')),
]

query\urls.py

from django.conf.urls import include, url
from . import views
urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^runQuery', views.runQuery, name='runQuery'),
]

view.py

Here you need to return a JSON object. One way to return it using the HttpResponse is by using simplejson.

from django.shortcuts import render
from django.http import HttpResponse
from django.utils import simplejson

def index(request):
     # this function powers the main page: 'http://127.0.0.1:8000/'
     List = ['item1','item2','item3']
     return render(request, 'query/home.html', {'list': List})


def runQuery(request):
    # this function needs to be called using $http from javascript 
    # I want to get what user submitted in $http and do something with it here
    # then return a list, below is a sample list 
    fruitList = simplejson.dumps("fruitlist" : ['apple', 'banana', 'orange'])
    return HttpResponse(fruitList, content_type ="application/json")

Upvotes: 1

C14L
C14L

Reputation: 12548

You coworker is correct, you are being redundant in you urls.py definitions.

For now, only use your main app's SimpleWeb/urls.py and build you URLs from there. Once you got that, you can learn how to separate them into parts and import them.

I guess these are the URLs you are looking for.

# SimpleWeb/urls.py
urlpatterns = [
    url(r'^$', query.views.index),
    url(r'^runQuery$', query.views.runQuery),
]

Next problem is you runQuery view, because it returns a list, but it has to return a str

def runQuery(request):
    fruitList = ['apple', 'banana', 'orange']
    return HttpResponse(fruitList)  # --> error: this is not a str!

Use Django's JsonResponse() to return the list as a a JSON encoded string.

def runQuery(request):
    fruitList = ['apple', 'banana', 'orange']
    return JsonResponse(fruitList)

Upvotes: 1

Related Questions