Here's the thing: I thought I could receive an HTTP response and manage it with javascript ajax and do whatever I wanted with that response without the user even noticing. For example using console.log(response). But it's not working and the response is showing in text form like an html.
I'll explain what I'm doing and my problem: I'm making a comment section for a django app. My comment system was working fine. The user could post comments and see other peoples comments. The thing is that I had to refresh the page every time to load the recently published comments.
That's not very cool, I want to be able to post a comment and see it immediately without reloading the page. I did my research and found this comment on quora
You use AJAX and a Django backend view. Something (a user leaving a new comment, a timer etc.) will trigger a JavaScript AJAX call to a Django view requesting comments for the page. That Django view will return the result to the JavaScript AJAX call. It can be done in two ways:
it can just return the data, typically in JSON and then JavaScript worries about rendering that data on the page
or, the view can run the data through a Django template and return the partial HTML and then the JavaScript just needs to swap out the HTML response chunk in the content area for the comments (typically identified by a HTML ID, where you replace the HTML content of the div with a certain ID with the HTML you received from the view both approaches have pros and cons and which is better depends on many factors
I am trying to follow the second way. My problem is that the HttpResponse changes my entire page and displays what's in the response as html text!
Here's my views.py. This is the view that renders the page where the comment section is at (I'm not sending the rendered html yet because I'm having problems with HTTP response)
def make_bid(request, pk):
listing = Listing.objects.get(id = pk)
comments = listing.comments.all()
if request.method == "POST":
if request.user.is_authenticated:
comment = Comment(
user = request.user,
comment= request.POST['comment'],
date = datetime.datetime.now().date(),
listing = listing)
comment.save()
context = {'comments': listing.comments.all()}
rendered = render_to_string("auctions/comments.html", context)
return HttpResponse("this a http response")
else:
return HttpResponse("user is not even authenticated")
else:
return render(request, "auctions/make-bid.html", {
'article' : listing,
'comments': comments
})
The html for the comment section
<aside class="comment__section">
<h3>Comments</h3>
<form action="{% url 'make-bid' article.id %}" method="post" id="form-comment">
{% csrf_token%}
<textarea id="textbox" class="field form__field--block" value="" name="comment" placeholder="What do you think about this listing?"></textarea>
<input class="button button__primary" type="submit" value="Publish">
</form>
<section class="comment__container">
<!-- comments from the http response should be inserted here with javascript-->
</section>
</aside>
The javascript. I copied this from another stackoverflow question. I was doing it myself with plain javascript and thought that might be the problem. It's not. It still doesn't give me the result I want
<script>
aside = document.querySelector(".comment__section")
// this is the id of the form
$("#from-comment").submit(function(e) {
e.preventDefault(); // avoid to execute the actual submit of the form.
var form = $(this);
var url = form.attr('action');
$.ajax({
type: "POST",
url: url,
data: form.serialize(), // serializes the form's elements.
success: function(data)
{
alert(data); // show response from the php script.
console.log('Submission was successful.');
console.log(data);
},
error: function(data){
console.log("no response")
}
});
});
</script>
I already tried using return JsonResponse. And still the same result :( I am really lost here. I'm very new to Django and server-side stuff. And I have no idea why is the response showing like a whole page? What am i missing? Do http responses actually work differently as I think they do? I would really appreciate any help. Thank you!!!
I fixed it! My main problem was me. I made a few stupid mistakes. I had a typo and jquery wasn't loading. Here's how the script looks now:
<script src="{%static 'auctions/scripts/jquery-3.6.0.js' %}"></script>
<script>
$(document).ready(function(){
$("#form-comment").submit(function(e) {
e.preventDefault(); // avoid to execute the actual submit of the form.
var form = $(this);
var url = form.attr('action');
$.ajax({
type: "POST",
url: url,
data: form.serialize(), // serializes the form's elements.
success: function(data)
{
$("#comments").html(data);
$("#textbox").val('')
},
error: function(data){
console.log("no response")
}
});
});
})
</script>
And views.py. Now I'm sending the rendered comment section with an HttpResponse
def make_bid(request, pk):
listing = Listing.objects.get(id = pk)
context = {'comments': listing.comments.all()}
rendered = render_to_string("auctions/comments.html", context)
if request.method == "POST":
if request.user.is_authenticated:
comment = Comment(
user = request.user,
comment= request.POST['comment'],
date = datetime.datetime.now().date(),
listing = listing)
comment.save()
context = {'comments': listing.comments.all()}
rendered = render_to_string("auctions/comments.html", context)
return HttpResponse(rendered)
else:
return HttpResponse("user is not even authenticated")
else:
return render(request, "auctions/make-bid.html", {
'article' : listing,
'comments': rendered
})
And html looks like this
<aside class="comment__section" >
<h3>Comments</h3>
<form method="post" id="form-comment">
{% csrf_token%}
<textarea id="textbox" class="field form__field--block" value="" name="comment" placeholder="What do you think about this listing?"></textarea>
<input class="button button__primary" type="submit" value="Publish">
</form>
<section class="comment__container" id="comments">
{{comments}}
</section>
</aside>
I would still love to see a way to make the ajax call and handle the response with javascript. But I'm done with this comments section for now! Thanks to everybody who answered this question!