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
Related
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
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.
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
I am doing a project management tool web application. I would like user can choose 'user' from dropdown selection, click 'Add member', then the member will show somewhere under the member?. Here is what I am doing.
Please do not worry about the styling. I have not done UI yet.
view.py
def member_select(request):
if request.method == 'GET':
selection = request.GET.get('id',None)
if selection:
selected_member = User.objects.filter(pk=selection)
return selected_member
project_index.html
<form action="" method="GET" id="selection-form">
{% csrf_token %}
<select id="member_list">
{% for user in user %}
<option>
{{ user.username }}
</option>
{% endfor %}
</select>
<input type="button" value="Add member" id="selection-button">
</form>
base.html
<script>
var url = $( '#selection-form' ).attr( 'action' );
$("selection-button").onclick(function (e) {
e.preventDefault();
$.ajax({
type:'GET',
url:url,
data:{
id:$('#member_list').val()
},
success:function (result) {
alert('okay');
},
error:function (result) {
alert('error');
}
});
});
</script>
Maybe use an empty <p class='member-name'><p> and
after choosing in the jquery success function
change to
success:function (result) {
$('.member-name').text(result);
},
try this (not fully tested)
from django.core import serializers
from django.http import HttpResponse
def member_select(request):
selection = request.GET.get('id',None)
if selection:
data = serializers.serialize('json',User.objects.filter(pk=selection))
else:
data = {}
return HttpResponse(data, content_type='application/json')
from the docs https://docs.djangoproject.com/en/2.0/topics/serialization/
In javascript ajax funtion the response should be a user object if exists or empty json string
<form action="" method="GET" id="selection-form">
{% csrf_token %}
<select id="member_list">
{% for user in user %}
<option value="{{user.pk}}">{{ user.username }}</option>
{% endfor %}
</select>
<input type="button" value="Add member" id="selection-button">
</form>
<di id='res'></div>
$("#selection-button").on('click', function(e) {
e.preventDefault();
var value =$('#member_list').val();
$.ajax({
type:'GET',
url:'.',
data:{
id:value
},
success:function (result) {
alert('okay');
$('#res').append(result);
console.info(result);
},
error:function (result) {
alert('error');
}
});
});
I've searched through similar questions, but nothing seems relevant to my situation.
Why does this code work fine:
<form action="/signup/" method="post">
{% csrf_token %}
[FORM]
</form>
but
<form id="signup-form">
{% csrf_token %}
[FORM]
</form>
<script type="text/javascript">
$(function() {
$(".submit-signup").on("click", function() {
var user = $("#signup_form").serialize();
console.log(user);
$.post("/signup/", user, function() {
});
});
});
</script>
not work?
Here is signup in views.py:
#requires_csrf_token
def signup(request):
[STUFF]
return render(request, 'signup.html', {[STUFF}})
What else can I provide that would help? Basically I am trying to take a page and turn it into a modal that does the same thing.
Thanks!
you are doing an ajax post call for which you need to give csrf token also:
$.post("/signup/", {
user: user,
csrfmiddlewaretoken: '{{ csrf_token }}'
}, function() {
// success todo
}, function(){
// fail todo
});