如何在Django中从JavaScript调用Python函数?

时间:2018-06-29 17:32:26

标签: python ajax django

我已经为此奋斗了几天。我已经阅读了许多有关Django项目的帖子,博客和观看视频演示,但没有什么能完全解决我的问题。

我有一个Django网络应用程序,该应用程序使用Python API连接到第三方服务以分析文本数据。用户写入文本区域,按下按钮,然后将文本发送到服务,该服务返回JSON对象列表。对该服务的API调用是Python函数。我试图使用Ajax在按下按钮时使用文本数据作为参数对Python函数进行异步调用。

目前,我还没有尝试调用我的第三方服务。我只是想看看我是否可以从Python发送输入和接收输出中得到响应。

我发现的大多数示例都涉及创建表单并提交表单,因此Django框架会自动调用它的Python函数。表单不完全是我要构建的表单,也不是要进入新页面以查看结果或刷新当前表单。

<!-- index.html -->
<html>
<head>
    <title>Test Data</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
    <script>

        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);
        }
    </script>
</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'


编辑:
我几乎可以正常工作了。我只是无法理解的ajax出现语法错误。

Could not parse the remainder: ' 'ajax-test-view'' from 'url 'ajax-test-view''

编辑
我修复了所有语法错误,但是现在尝试执行目标python脚本时遇到404错误。我现在了解url和路径在Django中的工作原理,但是使用Kostadin Slavov的解决方案,如何在不路由到特定html的情况下做到这一点?

在ajax中,我这样设置URL: url: '{{ 'ajax-test-view' }}', 在我的python中,我将url模式设置如下: path(r'^django-app/$', views.testcall, name = 'ajax-test-view'),

似乎ajax url中的变量指向url模式中的name字段,但这也似乎是要渲染的特定html文件的名称(?)还是py函数的名称?

当我单击我的按钮时,ajax向http://localhost:8000/what-ever-the-name-field-is-in-the-url-pattern发送命令,并从中获得404。框架是在尝试加载页面,还是意味着它找不到我的python文件?

Derp ...重要的是要知道url: '{{ 'ajax-test-view' }}',是ajax将请求的URL地址,而Django的url调度程序仅在路径完全匹配时才截取它以执行其他操作。

最终编辑
得到它的工作。我在Kostadin Slavov的解决方案中更改了几件事:

# urls.py
urlpatterns = [
   url(r'^$', views.index, name = 'index'),
   path('my-ajax-test/', views.testcall),
]

<!-- index.html -->
<script>
....

var text = "test successful";

$.ajax({
   type: "POST",
   url: '{{ 'my-ajax-test/' }}',
   data: { csrfmiddlewaretoken: '{{ csrf_token }}', text: text },
   success: function callback(response){
               console.log(response);
            }
});
</script>

# views.py
def testcall(request):
   return HttpResponse(request.POST['text'])

4 个答案:

答案 0 :(得分:1)

urls.py中创建一个url

path('my-ajax-test/', views.myajaxtestview, name='ajax-test-view'),

那你的ajax应该看起来像

请注意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);
           }
    });

views.py

def myajaxtestview(request):
    return HttpResponse(request.POST['text'])

摘要:

您需要在url中创建urls.py,这将导致您的views.py 那么该视图将获取您在request.POST的{​​{1}}中发送的数据,您将拥有大量的数据here。 就您而言,您对request更感兴趣,这是一个python字典 所以您选择要发送的参数并使用它 您可以像request.POST

一样玩

如果您想从return HttpResponce('test'+ request.POST['text'])那里得到一些东西,那么假设您从js发送的数据是models.py

{object_type: hammer}

答案 1 :(得分:0)

您要尝试的是一个众所周知的问题。当您向服务器发出ajax请求时,服务器将以一些数据响应或可能呈现一个模板。

要使此请求-响应周期起作用,您将必须创建url到控制器逻辑的映射。您将必须在urls.py中创建一个url和一个python函数映射。 python函数将在views.py中。现在,当您使用给定方法(POST或GET)请求该网址时,它将调用映射函数并返回结果。

答案 2 :(得分:0)

  

阅读问题编辑和不同答案后,这是   对我有用的东西(不包括进口):

文件:urls.py

#urls.py
urlpatterns = [
   path('', views.index, name = 'index'),
   path('my-ajax-test/', views.testcall),
]

文件:index.html

#index.html
<html>
<head>
    <title>Test Data</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
    <script>

        function analyzeText(){
            var text = document.getElementById('text-to-analyze').value;

            $.ajax({
                type: "POST",
                url: '{{ 'my-ajax-test/' }}',
                data: { csrfmiddlewaretoken: '{{ csrf_token }}', text: text },  
                success: function callback(response){
                           /* do whatever with the response */
                           alert(response);
                        }
            });
        }
    </script>
</head>
<body>
    <textarea id="text-to-analyze" rows="12" cols="100"></textarea><br>
    <input type="submit" id="button" value="process" onclick="analyzeText();">

</body>
</html>

文件:views.py

#views.py
def index(request):
   return render(request, 'vote/index.html')

def testcall(request):
   #Get the variable text
   text = request.POST['text']
   #Do whatever with the input variable text
   response = text + ":)"
   #Send the response 

   return HttpResponse(response)

答案 3 :(得分:0)

我在这个问题上苦苦挣扎了一两天。这是解决我的问题的方法。

编辑:我还需要下载完整版本的jquery才能使ajax请求正常工作。

HTML

在您的HTML中,您需要向表单中添加{%csrf_token%}

<form id="your_form">
    {% csrf_token %}  //include the csrf_token line in your form
    <div>
        <input type="submit" value="blah blah blah">
    </div>
 </form>

script.js

对于您的Java脚本代码,请添加此函数以获取csrf cookie。

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = cookies[i].trim();
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

接下来,您需要按如下所示将csrf令牌添加到ajax请求中。

    var csrftoken = getCookie('csrftoken');

    $.ajax({
       type: "POST",
       url: '/my-url/', --your url here
       data: { csrfmiddlewaretoken: csrftoken, text: "your text data here" },
       success: function callback(response){
                   console.log(response);
                }
    });