I am trying to post comment with ajax, but it is not working. When I press button console is not printing any error (like 404 etc.), comment is not being posted. Object returned by error:
{readyState: 4, getResponseHeader: ƒ, getAllResponseHeaders: ƒ, setRequestHeader: ƒ, overrideMimeType: ƒ, …} abort: ƒ (e) always: ƒ () catch: ƒ (e) done: ƒ () fail: ƒ () getAllResponseHeaders: ƒ () getResponseHeader: ƒ (e) overrideMimeType: ƒ (e) pipe: ƒ () progress: ƒ () promise: ƒ (e) readyState: 4 responseText: "↵" setRequestHeader: ƒ (e,t) state: ƒ () status: 200 statusCode: ƒ (e) statusText: "OK" then: ƒ (t,n,r) proto: Object
In command line I see:
"POST / HTTP/1.1" 200 5572
When I change button to "submit" it is posting and responding with proper JSON like:
{"comment": {"id": 16, "author": 1, "content": "test", "post": 12}}
My code is below, any help is appreciated:
views.py
def homepage(request):
profiles = Follow.objects.filter(follow_by=request.user.profile).values_list('follow_to', flat=True)
posts = Post.objects.filter(author_id__in=profiles).order_by('-date_of_create')
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
pk = request.POST.get('pk')
post = Post.objects.get(pk=pk)
new_comment = Comment.objects.create(
author = request.user.profile,
post = post,
content = form.cleaned_data['content']
)
return JsonResponse({'comment': model_to_dict(new_comment)}, status=200)
form = CommentForm()
context = {
'posts': posts,
'form': form
}
return render(request, 'posts/homepage.html', context=context)
template
<div class="comments" id="{{ post.pk }}" style="display: none">
{% include 'posts/comments.html' %}
<form action="" method="post" class="commentForm" data-url="{% url 'post_comments' post.pk %}">
{% csrf_token %}
<input type="hidden" name="pk" value="{{ post.pk }}">
{{ form.as_p }}
<button type="button" class="commentBtn" id="{{ post.pk }}">Comment</button>
</form>
addComment.js
$(document).ready(function () {
$('.commentBtn').click(function () {
let serializedData = $('.commentForm').serialize();
let btn = $(this);
let id = btn.attr('id');
console.log($(".commentForm").data('url'));
$.ajax({
url: $(".commentForm").data('url'),
data: serializedData,
type: 'post',
dataType: 'json',
success: function (data) {
console.log(data);
$(`#${id}.comments`).load('/posts/comments/' + data.post);
$('textarea').val('');
},
error: function(textStatus) {
console.log(textStatus)
}
})
})
})
Edit:
I used this question: Ajax request returns 200 OK, but an error event is fired instead of success
, deleted dataType: 'json'
and added contentType: 'application/json'
and now I got 403 error.
As you have use $('.commentForm')
to send data of form to backend it will get all forms with class commentForm
and send data of all forms that's the reason its not working .Instead you can change this $('.commentForm').serialize()
to $(this).closest(".commentForm").serialize()
.
Also , you are using #${id}.comments
inside success function of ajax this will override any content inside #${id}.comments
and load new content from url i.e : /posts/comments/..
.So , to avoid this one way would be surround your {% include 'posts/comments.html' %}
with some outer div and then change your selector i.e : #${id}.comments > .yourouterdivclassname
so new content will be loaded inside that div
only thus form will not get removed .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With