How I can update my objects in template dynamically? - python

I have comments on a product on the page. and there is a button to add a comment, which puts a new comment into the database. How can I automatically display a new comment on a page?
mytemplate.html
<div id="comments">
{% include 'comments.html' %}
</div>
comments.html
{% for comment in comments %}
<!-- some code for display comments -->
{% endfor %}
script.js
$("#addComment").on("click", function(e){
e.preventDefault()
if ($("#addCommentArea").val() != ""){
data = {
commentText: $("#addCommentArea").val(),
product_id: "{{ product.id }}"
}
$.ajax({
type: "GET",
url: "{% url 'newcomment' %}",
datatype: 'json',
data: data,
success: function(data){
$("#addCommentArea").val("")
}
})
}
})
views.py
class CommentView(View):
def get(self, request):
commentText = request.GET.get("commentText")
if (len(commentText) > 0):
newComment = Comment()
newComment.Author = request.user
product_id = request.GET.get("product_id")
product = Product.objects.get(id=product_id)
newComment.Product = product
newComment.Comment = commentText
newComment.save()
return JsonResponse({'ok': 'ok'})

Currently, you just render the template once and fetch the comments, further you are using Ajax to submit, which means your template doesn't get updated. To update the comments without a page refresh you can either make a javascript polling or use for example web sockets

Related

Not Found url in django class based view with ajax

I have a problem with "like" functionality. I want to make it possible to like the post, without overloading the whole page. So I used CBV django connected to ajax.
My problem is that it receives: Not Found: /like/ by pressing the "Like" button.
My view:
class PostLikeView(generic.View):
def post(self, request):
post = get_object_or_404(Post, id=request.POST.get('id'))
is_liked = False
if post.likes.filter(id=request.user.id).exists():
post.likes.remove(request.user)
is_liked = False
else:
post.likes.add(request.user)
is_liked = True
context = {
'post': post,
'is_liked': is_liked,
'total_likes': post.total_likes(),
}
if request.is_ajax():
html = render_to_string('post/like_section.html', context, request=request)
return JsonResponse({'form': html})
Below is jquery code:
<script type="text/javascript">
$(document).ready(function(event){
$(document).on('click', '#like', function(event){
event.preventDefault;
var pk = $(this).attr('value');
$.ajax({
type: 'POST',
url: "{% url 'post:post_like' %}",
data: {'id': pk, 'csrfmiddlewaretoken': '{{ csrf_token }}'},
dataType: 'json',
success: function(response){
$('#like-section').html(response['form'])
console.log($('#like-section').html(response['form']))
},
error: function(rs, e){
console.log(rs.responseText);
},
});
});
});
</script>
url to view:
url(r'^like/$', login_required(PostLikeView.as_view()), name='post_like'),
code in html:
<form action="{% url 'post:post_like' %}" method="post">
{% csrf_token %}
{% if is_liked %}
<button type="submit" id="like" name="post_id" value="{{ post.id }}" class="btn btn-danger">Dislike</button>
{% else %}
<button type="submit" id="like" name="post_id" value="{{ post.id }}" class="btn btn-primary">Like</button>
{% endif %}
</form>
I would like the button to work on the principle of not reloading the whole page.
The issue I think is that you've not actually called event.preventDefault in your click event handler (you're missing the brackets). That means that the submit button submits the form, but the form doesn't contain a parameter named id and so get_object_or_404(Post, id=request.POST.get('id')) raises a 404.
Add the missing brackets to event.preventDefault, and also note that the value of id= attributes on HTML elements should be unique within the page. Change the values of the id= attributes on the <button> elements so that they are unique.

Django : SQLite Database is Locked when I build like feature on my home page

I am implementing Like functionality in Web application. Idea is Simple to List number of Post(Blogs) on Home page and Add a Like Button to each post(Blog). It works fine when I build it with normal
<form action='{% url target %}' method='POST'>
But when I implemented this with AJAX call It only allows me to like or dislike a particular post(blog) a single time.i.e One I liked a Post for first time it works, also when I dislike the same Post It works fine, But when I again Like that Post it throws an django.db.utils.OperationalError: database is locked
Also, when I like same post multiple(4 to 5) times it respond in a weird way. I goes in Loop of liking and dislikig post.
like_section.html
<form id="like-form{{ post.id }}">
{% csrf_token %}
<button type="submit" id="{{ post.id }}btn" name="like" value="{{ post.id }}" class="btn upvote">Like</button>
<script type="text/javascript">
{% for like in post.likes.all %}
{% if like != user %}
dislikingPost("{{ post.id }}btn");
{% else %}
likingPost("{{ post.id }}btn");
{% endif %}
{% endfor %}
$(document).ready(function(event){
$(document).on('click', '#{{ post.id }}btn', function(event){
event.preventDefault();
pk = $(this).attr('value');
$.ajax({
type: 'POST',
url: '{% url "like_post" %}',
data: {
'id': pk,
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
success:function(response){
$('#like-form{{ post.id }}').html(response['form'])
// $('#{{ post.id }}btn').style.color = 'green';
}, error: function(er, e){
console.log(er.responseText);
}
});
});
});
</script>
</form>
views.py:
def like_post(request):
all_posts = Posts.objects.all()
print("Insisde Like Post")
print('ID coming from form is', request.POST.get('id'))
post = get_object_or_404(Posts, id=request.POST.get('id')) # for AJAX call
context = {
'all_posts': all_posts,
'post': post
}
if post.likes.filter(id=request.user.id).exists():
post.likes.remove(request.user) # Liking The Post
print("DisLiking the post")
else:
post.likes.add(request.user)
print("Liking the post")
if request.is_ajax():
print('Hey its an AJAX calls') # TEsting AJAX request
html = render_to_string('like_section.html', context, request=request)
return JsonResponse({'form': html})
Note:
1. I am beginner in AJAX.
2. I know SQLite can not handle redundant calls, But why it was working before without AJAX calls.
3. I am not providing models.py and complete template of home page and I don't think they are required.
The Problem was not with the Django code. It was ajax call which was triggering Database more then one time on a single Button Click.
Adding event.stopImmediatePropagation(); below event.preventDefault(); in ajax call works perfect

Django ajax redirecting on form submission

I'm trying to return data with an ajax request on a form submission. My goal was too use two views, one too handle the template loading and the other to handle the POST request from the form. In the current state, the form is redirecting to the JSON that is in the callback. That makes sense as it's for the form action url is pointing, however, i want to just pass the data to the current page and not reload the page or be redirected to another page.
Here is the code:
user.html
<form action="{% url 'ajax-user-post' %}" method="post">
{% csrf_token %}
{% for user in users %}
<input type="submit" name="name" value="{{ user }}">
{% endfor %}
views.py
def ajax_user(request):
# get some data..
if request.METHOD == 'POST':
user = request.POST['user']
user_data = User.objects.get(user=user)
data = {'user_data': user_data}
return JsonResponse(data)
def user(request):
return render(request, 'user.html', context)
urls.py
url(r'^user/', user, name="user"),
url(r'^ajax/user/', ajax_user, name="ajax-user-post")
.js
$('form').on('submit', function(){
var name = // the name of the user selected
$.ajax({
type: "POST",
dataType: "json",
url: 'ajax/user/',
data: { 'csrfmiddlewaretoken': csrftoken, 'name': name, 'form': $form.serialize() },
success:function(data) {
// hide the current data
console.log(data);
displayUserData(data)
}
})
});
Thanks for the help in advance!
i want to just pass the data to the current page and not reload the page or be redirected to another page.
That means you need to stop the form submission event with the event.preventDefault() call.
Hence, change this line from:
$('form').on('submit', function(){
to to following two:
$('form').on('submit', function(e){
e.preventDefault();

How do I change my queryset using AJAX?

I want to be able to change my comments queryset without page refresh. Here are the querysets:
comment_list = Comment.objects.filter().order_by('-score__upvotes')
new_comments_list = Comment.objects.filter().order_by('-timestamp')
Then my template is
{% for comment in comment_list %}
{{ comment }}
...
Is there any way to change {% for comment in comment_list %} to {% for comment in new_comments_list %} using AJAX (no page refresh)?
Or possibly changing the value of comment_list to equal Comment.objects.filter().order_by('-timestamp')?
EDIT
view:
def new_comments(request):
if request.is_ajax():
print('ajax') #prints ajax
comment_list = Comment.objects.filter().order_by('-timestamp')
html = render_to_string('article.html', {'comment_list': comment_list})
return HttpResponse(html)
ajax call:
$('.comments_new').on('click', function() {
$.ajax({
type: 'GET',
url: '/new_comments/',
data: {
csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val(),
},
success: function (data) {
console.log(data.comment_list); // undefined
}
})
});
What I guess, you are trying to use comment_list when page renders and new_comment_list using ajax without modifying
{% for comment in comment_list %}
{{ comment }}
{% endfor %}
The problem with your code is comment_list is a queryset and it is evaluated on the server side, when the page is rendered (after passing through Django template engine ).Javascript doesn't understand queryset. It understands HTML or JSON. So, you have to modify your script so that it return HTML or JSON for ajax request.
I would suggest you re-write your view like:
from django.template.loader import render_to_string
if request.is_ajax():
new_comments_list = Comment.objects.filter().order_by('-timestamp')
# you can keep your_div_template as a included template in your main template
html = render_to_string('your_div_template', {'comment_list': new_comments_list})
return HttpResponse(html)
And write your frontend to generate this HTML code.
here is a link that gives more better explanation of rendering using ajax: Returning Rendered Html via Ajax

Django Ajax form submission pointing to a 403 Forbidden

I'm allowing users to remove posts through ajax. Posts have a boolean field live_until_removed. When set to false, the post disappears.
When clicking remove I'm given a 403, referencing:
xhr.send( ( s.hasContent && s.data ) || null );
How do I get this to run smoothly? Why this this error happening?
js:
$('#removeForm').submit(function() { // catch the form's submit event
$.ajax({
data: $(this).serialize(),
type: $(this).attr('method'),
url: $(this).attr('action'),
success: function(response) {
$('.close-post').html(response); // update the DIV
console.log(response);
},
error: function(response){
console.log(response);
}
});
return false;
});
template:
<div class="close-post">
{% if not post.live_until_removed %}
<form class="" id="removeForm" method="POST" action="">
<button type="submit" class="btn">Remove</button>
</form>
{% else %}
<button class="btn">Removed</button>
{% endif %}
</div>
views.py:
def post(request, id):
...
if request.is_ajax():
try:
post = Post.objects.get(id=id)
post.live_until_removed = False
post.save()
response = simplejson.dumps({"status": "Removed"})
except:
pass
You might have missed to send CSRF token in your request. Look at here; Django-Ajax

Categories

Resources