无法使用 crispy returns 没有 csrf_token 的新表单验证表单

Fail to validate a form using crispy returns a new form without csrf_token

我正在尝试使用 Crispy 通过对我的 Django 项目的 Ajax 请求来验证表单。

问题是:如果表单无效,Crispy return 一个没有标签 {% csrf_token %} 的新表单,因此不起作用。

View.py

from jsonview.decorators import json_view
from crispy_forms.utils import render_crispy_form
from crispy_forms.helper import FormHelper
from django.shortcuts import render, render_to_response
from django.views.decorators.csrf import csrf_protect
from django.http import HttpResponse
from django.template import RequestContext
...and other stuff...

@json_view
@csrf_protect
def checkForm(request):
form = ExecutionForm(request.POST or None)  # request POST?
if form.is_valid():  # processa
    return experiments(request)
else:
    helper = FormHelper()
    helper.form_id = 'form_exec'
    helper.disable_csrf = False
    form_html = render_crispy_form(form, helper, RequestContext(request))
    return {'success': False, 'form_html': form_html}
    # return render(request, "experiments.html", {'success': False,
    # 'form_html': form_html})


@csrf_protect
def experiments(request):
if request.method == 'POST':
    print request.POST
    opt = request.POST.get('opt')
    algorithm = request.POST.get('Algorithm')
    d_User = User.objects.get(username=request.user)
    alg = Algorithms.objects.get(nameAlg=algorithm)
    execution = Execution(
        request_by=d_User.usuariofriends,
        #     status=form.cleaned_data.get("status"),
        algorithm=alg,
        opt=opt,  # very tenso
    )
    execution.save()
    query = alg.command
    print(query)
    os.system(query)
    cont = {}
    cont['success'] = True
    return cont
    # return render(request, "experiments.html", asd)
form = ExecutionForm(request.POST or None)
title = "Experiments %s" % (request.user)
context = {
    "title": title,
    "form": form
}
return render(request, "experiments.html", context)

javascript

function create_post(){
toggleFormWait();
$.ajax({
    url : "checkForm", 
    type : "POST",
    data : $('#form_exec').serialize(),
     // {

        // opt : $('#id_opt').val(),
        // Algorithm : $('#id_Algorithm').val()
    // },
    //handle successful
    success : function(data){
        toggleFormWait();
        console.log(data)
        if (!(data['success'])) {
            //console.log(data['form_html']);
            $('#formContent').replaceWith(data['form_html']);
        }
    },

    error : function(xhr,errmsg,err){
        toggleFormWait();
        console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
    }

});
};

HTML

<form id='form_exec' method='POST' action='.'>
    {% csrf_token %}
    {{form|crispy}}               
</form>

我设法找到了这个问题的解决方案,使用 jQuery 替换通过 ajax 收到的新表单无效的表单输入。但是,我认为这个解决方案有点难看。

有一个优雅的解决方案吗?

看看Django docs on CSFR when using JavaScript

您需要设置 X-CSRFToken header。链接的文档有一个完整的示例。