该代码应该做的是让用户点击他们的描述并能够编辑它。我弹出模式,但保存按钮不会保存数据并产生以下错误:
Uncaught ReferenceError: csrftoken is not defined
at HTMLButtonElement.<anonymous> (modalShortListDescription.js:6)
at HTMLButtonElement.dispatch (jquery.min.js:3)
at HTMLButtonElement.r.handle (jquery.min.js:3)
这是调用模态的地方:
<div class="tab-content col-xs-12">
{% for list in lists %}
<input type="hidden" id="idList" id_list="{{list.id}}">
{% if forloop.first and not createTabActive %}
<div role="tabpanel" class="tab-pane fade active in" id="list{{list.id}}">
{% else %}
<div role="tabpanel" class="tab-pane fade" id="list{{list.id}}">
{% endif %}
<div class="content col-xs-12">
<div class="form-horizontal sort-by col-xs-12">
<h3>Description</h3>
{% if list.description %}
<a href="#" data-toggle="modal" data-target="#modalDescription{{list.id}}" id="editDescription">{{list.description}}</a>
{% else %}
<a href="#" data-toggle="modal" data-target="#modalDescription{{list.id}}">None</a>
{% endif %}
{% include "layout/popUp/modal-short-list-description.html" %}
</div>
这是模态本身:
<div class="modal fade" id="modalDescription{{list.id}}" role="dialog">
<div class="modal-dialog">
<form class="form-horizontal" action="{% url 'update-list-description' %}" method="post">
{% csrf_token %}
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Description</h4>
</div>
<div class="modal-body modal-body-exper modal-body-value modal-body-t">
<div class="lineEnterValue lineTeamSize lineTitle">
<div class="form-group {% if form.description.errors %} has-error{% elif form.is_bound %} has-success{% endif %}">
<div class="col-sm-10">
<textarea name="{{ form.description.html_name }}" class="form-control" id="{{ form.description.id_for_label }}" rows="5" style="margin: 0px; height: 90px; width: 455px;"></textarea>
</div>
{% if form.description.errors %}
<ul class="col-sm-10 col-sm-offset-2 error-list text-danger">
{% for error in form.description.errors %}
<li>{{ error|escape }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
</div>
<div class="modal-footer modal-footer-value">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary" id="description_save">Save</button>
</div>
</div>
</form>
</div>
以下是保存按钮使用的.js:
$(document).ready(function() {
$("#description_save").click(function() {
var description = $("#form.description").val();
var idList = $("#idList").attr("id_list");
var url = "/bid/update-list-description";
csrftoken();
$.ajax({
type: "POST",
url: url,
data: {description : description, idList: idList},
}).done(function(response){
$(".modalDescription").modal("hide");
$(".editDescription").text(description);
});
})
})
编辑:views.py:
@csrf_protect
def updateListDescription(request):
checkEmployer(request)
pageClass="my-short-lists search-for-prospect"
#shortList = get_object_or_404(List, id = request.POST.get("idList"))
shortList = request.user.profile.profile_employers.employer_lists.filter(pk=request.POST.get("idList"))
if request.method =="POST":
form = ListForm(request.POST)
if form.is_valid():
shortList.description = form.cleaned_data["description"]
shortList.save()
else:
form = ListForm()
return redirect('my-short-lists')
AJAX POST不包含csrf_token。加:
'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val()
到$ .ajax数据(连同description和idList)并删除csrftoken()。
编辑你的js到此
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 = jQuery.trim(cookies[i]);
// 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;
}
$(document).ready(function() {
$("#description_save").click(function() {
var description = $("#form.description").val();
var idList = $("#idList").attr("id_list");
var url = "/bid/update-list-description";
var csrftoken = getCookie('csrftoken');
$.ajax({
type: "POST",
url: url,
data: {description : description,
idList: idList,
csrfmiddlewaretoken: csrf_token
},
}).done(function(response){
$(".modalDescription").modal("hide");
$(".editDescription").text(description);
});
})
})
编辑:
我认为问题不仅在于csrftoken
,还在于按钮:如果一个按钮调用ajax,它不应该是submit
。如果它发布表单,则不应该执行ajax调用。看来你在表单中添加了令牌,但是ajax先做了他的事......所以第一个答案似乎是有效的。
要么,
您可以在$.ajaxSetup()
中为每个ajax调用添加标头。 DOC对此部分进行了解释:
getCookie(name)
方法;var csrftoken = getCookie('csrftoken');
;那是:
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
https://docs.djangoproject.com/en/2.0/ref/csrf/,在“Ajax”部分。
我使用过这种方法并且有效。