When I use ajax to submit a comment form in Django,the page will redirect to a blank page shows me the success data:
{\"status\":\"success\", \"msg\":\"添加成功\
Finally I made it!Thanks Lord!Very excited!
I have Three major issues in my previous code.
First:Since the ajax will post the news_pk to the view update_comment,so I don't need add news_pk in this view's url and template(in the url of <form>
tag and the url in the ajax),so I removed them,or the data will still pass through Form but not ajax.
Second:My binding is incorrect,I have the click handler on the form it should be a submit handler. If I was binding it to a button then I'd use click a handler.Ajax not work in Django post But for this part I'm still a some confused,between the button summit way and form submit way.
The third issue is I mistaked 'comments' and 'comment'.'comment' is the name attribute of <textarea>
,through which forms.py gets the data.
comments is defined by ajax through var comments = $("#js-pl-textarea").val(),
so in the view I need use comments = request.POST.get("comments", "")
but not comment,that's the reason why 'post failed'.
Following is my code.
Here is the ajax:
$("#comment_form").submit(function(){
var comments = $("#js-pl-textarea").val()
$.ajax({
cache: false,
type: "POST",
url:"{% url 'operation:update_comment' %}",
data:{'news_pk':{{ news.pk }}, 'comments':comments},
async: true,
beforeSend:function(xhr, settings){
xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
},
success: function(data) {
if(data.status == 'fail'){
if(data.msg == '用户未登录'){
window.location.href="login";
}else{
alert(data.msg)
}
}else if(data.status == 'success'){
window.location.reload();//refresh current page.
}
},
});
return false;
});
Here is my udate_comment view:
@login_required
def update_comment(request):
news_pk = request.POST.get("news_pk", 0)
comments = request.POST.get("comments", "")
if int(news_pk) > 0 and comments:
news_comments = NewsComments()
news = News.objects.get(id=int(news_pk))
news_comments.news = news
news_comments.comments = comments
news_comments.user = request.user
news_comments.save()
return HttpResponse('{"status":"success", "msg":"添加成功"}', content_type='application/json')
else:
return HttpResponse('{"status":"fail", "msg":"添加失败"}', content_type='application/json')
Here is my form in template:
<form id="comment_form" action="{% url 'operation:update_comment'%}" method="POST" >
{% csrf_token %}
<textarea id="js-pl-textarea"name="comment"></textarea>
<input type="submit" value="Submit"> </input>
</form>
I really appreciate everyone's reply!With your reply I figured out these issue step by step!
I have something similar in my project. Its a script to like a song. I'm just gonna put the relevant codes here.
like_script.html
. I call it in a template using django template include
<script>
$('#like').click(function(){
$.ajax({
type: "POST",
url: "{% url 'song:like_song' %}",
data: {'pk': $(this).attr('pk'), 'csrfmiddlewaretoken': '{{ csrf_token }}'},
dataType: "json",
success: function(response) {
alert(response.message);
},
error: function(rs, e) {
alert(rs.responseText);
}
});
})
</script>
The django view
import json
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_POST
@login_required
@require_POST
def song_like_view(request):
if request.method == 'POST':
user = SiteUser.objects.get(user=request.user)
pk = request.POST.get('pk', None)
song = get_object_or_404(Song, pk=pk)
if song.likes.filter(pk=user.pk).exists():
song.likes.remove(user)
song.like_count = song.likes.count()
song.save(update_fields=['like_count'])
message = "You unstarred this song.\n {} now has {} stars".format(song.title, song.like_count)
else:
song.likes.add(user)
song.like_count = song.likes.count()
song.save(update_fields=['like_count'])
message = "You starred this song.\n {} now has {} stars".format(song.title, song.like_count)
context = {'message' : message}
return HttpResponse(json.dumps(context), content_type='application/json')
The url
urlpatterns = path("like/", views.song_like_view, name='like_song'),
<a class="btn btn-sm btn-primary" href="" id="like" name="{{ song.pk }}" value="Like"></i> Unstar</a>
{% include 'like_script.html' %}
Same button for like and unlike. I hope you can follow the logic to make yours right. Notice that in your view you don't need to include the pk. Just get it from the POST
data pk = request.POST.get('pk', None)