Как вызвать функции Python из JavaScript в Django? - PullRequest
0 голосов
/ 29 июня 2018

Я боролся с этим пару дней. Я прочитал много постов, блогов и посмотрел демоверсию видео о проектах Django, но ничего не решает мою проблему.

У меня есть веб-приложение Django, использующее API-интерфейс Python для подключения к стороннему сервису для анализа текстовых данных. Пользователь пишет в текстовую область, нажимает кнопку, затем текст отправляется в службу, которая возвращает список объектов 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'


EDIT:
У меня почти все работает. Я просто получаю синтаксические ошибки с ajax, я не могу понять.

Не удалось проанализировать остаток: '' ajax-test-view '' из 'url' ajax-test-view ''

EDIT
Я исправил все синтаксические ошибки, но теперь я получаю 404 ошибки при попытке выполнить целевой скрипт Python. Теперь я понимаю, как работает url и pathing в Django, но, используя решение Костадина Славова, как я могу сделать это без маршрутизации к определенному html?

В ajax я устанавливаю URL следующим образом: url: '{{ 'ajax-test-view' }}', И в моем Python шаблон URL установлен так: path(r'^django-app/$', views.testcall, name = 'ajax-test-view'),

Кажется, что переменная в URL-адресе ajax указывает на поле имени в шаблоне URL-адреса, но это также имя конкретного HTML-файла для рендеринга (?) Или это имя функции py?

Когда я нажимаю кнопку, ajax отправляет команду на http://localhost:8000/what-ever-the-name-field-is-in-the-url-pattern, и я получаю от нее 404. Фреймворк пытается загрузить страницу или это означает, что он не может найти мой файл python?

Сумасшедший ... Важно знать, что url: '{{ 'ajax-test-view' }}', - это URL-адрес, который будет запрашивать ajax, и диспетчер URL-адресов Django перехватывает его, чтобы сделать что-то еще, только если путь полностью совпадает.

ОКОНЧАТЕЛЬНОЕ РЕДАКТИРОВАНИЕ
Получил это работает. Пара вещей, которые я изменил в решении Костадина Славова:

# 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'])

Ответы [ 3 ]

0 голосов
/ 29 июня 2018

То, что вы пытаетесь - это хорошо известная проблема. Когда вы делаете ajax-запрос к серверу, сервер отвечает некоторыми данными или может отображать шаблон.

Для того, чтобы этот цикл запроса-ответа заработал, вам необходимо создать отображение URL-адреса на логику контроллера. Вам нужно будет создать отображение url и функции python в urls.py. Функция python будет в views.py. Теперь, когда вы запрашиваете этот URL с помощью данного метода (POST или GET), он вызывает функцию отображения и возвращает результат.

0 голосов
/ 24 июля 2019

После прочтения правок вопроса и различных ответов, это что сработало для меня (не включает импорт ):

Файл: 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)
0 голосов
/ 29 июня 2018

в 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 в request, у вас есть много данных, вы можете найти больше об этом здесь . в вашем случае вас больше интересует request.POST это словарь питона поэтому вы выбираете параметр, который вы отправляете, и работаете с ним вы можете играть с ним как return HttpResponce('test'+ request.POST['text'])

Если вы хотите получить что-то от models.py, скажем, ваши данные, которые вы отправили с js, это {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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...