如何通过javascript文件中的ajax调用在views.py中调用特定函数?

时间:2018-02-20 04:38:58

标签: javascript python ajax django

在Django中,我们将URL映射到views.py中的函数。 如果我们进行ajax调用,那么我们需要在ajax调用中提到url,但这将调用映射到该url的函数。 我想通过ajax调用从views.py调用特定的函数? 我该怎么做才能通过AJAX调用调用views.py中的任何函数而不更改url?

views.py

def index(request):
    codes=Code.objects.all()[:10]
    context={
        'name': 'KD',
        'codes': codes
    }
    return render(request,'coding/index.html',context)


def details(request):
    code=Code.objects.get(1)
    context={
        'code': code
    }
    return render(request, 'coding/details.html', context)

urls.py

from django.contrib import admin
from django.urls import path,include
from . import views

urlpatterns = [
    path('',views.index, name="index" ),
    path('details',views.details, name="details" ),
];

的javascript

<script type="text/javascript">
   $(document).ready(function() {
       $("#tests").submit(function(event){
       event.preventDefault();
            $.ajax({
                 type:"POST",
                 url:"/details/",  // what changes should be done so that I can call other function in views.py?
                 data: {
                        'video': $('#tests').val() 
                        },
                 success: function(){
                     $('#message').html("<h2>Code Submitted!</h2>") 
                    }
            });
            return false;
       });

    });
</script>

3 个答案:

答案 0 :(得分:0)

只需在视图中包装函数调用,并像通常的视图一样使用它。例如,您有一个功能:

   def print_hello():
       print("Hello!")

你应该创建视图:

   def print_hello_view(request):
       print_hello()
       return HttpResponse(status=200)

并将其添加到网址:

    path('print-hello',views.print_hello_view, name="print_hello_view"),

在模板中用新端点替换ajax url:

    {% url 'print_hello_view' %}

如果你想有可能选择功能,你应该添加一些条件。

答案 1 :(得分:0)

我认为Nikitka所说的是你可以在详细信息视图中监听POST请求并使用它来运行你的其他python函数。尝试以下内容:

def details(request):
    # Check if there was a POST request that contains the 'video' key
    if 'video' in request.POST:
        # Run your python script here.

    code=Code.objects.get(1)
    context={
        'code': code
    }
    return render(request, 'coding/details.html', context)

如需进一步阅读,我想推荐Vitor Freitas&#39; blog

答案 2 :(得分:0)

我不确定你为什么要这样做,从安全角度来看,这是一个坏主意。允许访问任意函数是可以利用的,所以你应该避免使用它。

ajax客户端需要事先知道内部函数的名称,以便它可以调用它们,并且可能还知道可以将哪些参数传递给函数。如果客户端具有该信息,那么您可以明确地公开urls.py中的函数并将其留在那里。

在提出反对意见后,您可以实现一个调度视图函数,该函数接受请求并使用globals()['function_name']委托给请求中指定的函数。

假设要调用的函数是返回适当值(呈现HttpResponse,JSON等)的视图函数,您的视图可能如下所示:

def call_named_function(request, function_name):
    try:
        return globals()[function_name](request)
    except KeyError:
        return JsonResponse({'error': True, 'message': 'Function {!r} not found'.format(function_name)}, status=404)
    except Exception, exc:
        return JsonResponse({'error': True, 'message': 'Exception calling function {!r}: {}'.format(function_name, exc)}, status=500)

添加到urls.py的路由以捕获函数名称并调用视图函数:

path('call/<function_name>', views.call_named_function, name='call'),

现在,您可以向代码添加视图函数,或从其他模块导入它们,并使用附加到URL的函数名称调用它们:

http://127.0.0.1:8000/call/function_1
http://127.0.0.1:8000/call/some_function

我认为使用上述内容更容易,但如果您不想更改URL,则必须在POST请求的主体中添加一些内容,指定要调用的函数的名称:

def call_named_function(request):
    try:
        function_name = request.POST['function_name']
        return globals()[function_name](request)
    except KeyError:
        return JsonResponse({'error': True, 'message': 'Function {!r} not found'.format(function_name)}, status=404)
    except Exception as exc:
        return JsonResponse({'error': True, 'message': 'Exception calling function {!r}: {}'.format(function_name, exc)}, status=500)

有路线:

path('call', views.call_named_function, name='call'),

并POST名称为'function_name'的请求中要调用的函数的名称。

您还可以将参数作为位置参数的JSON编码列表和关键字参数的JSON编码序列进行POST。