Ajax form not sending data in django - python

I am trying to send data to Django without page refresh. So I am using ajax.
Created a Django model and form
class MyModel(models.Model):
text=models.CharField(max_length=100)
class MyForm(forms.ModelForm):
class Meta:
model=MyModel
fields = "__all__"
Then send the form to the HTML page via views.py
def home(request):
print(request.POST.get('text',False))
form = MyForm(request.POST)
if request.method=='POST':
print(request.POST.get('text',False))
if form.is_valid():
data=form.save()
return render(request,'home.html',{'form':form})
Create a form in HTML template
<form action = "" id="post-form" method = "post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="submit" id="submit-button">
</form>
This is the javascript file
$(document).on('submit','#post-form',
function(x){
x.preventDefault();
console.log("button clicked")
$.ajax({
type:'POST',
url:'/',
data:{
text:$("id_text").val(),
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
},
success:function(){
alert('Saved');
}
})
}
)
I think it might be the issue with URL, if i set url like this way
url:'{% url "home" %}',
Then in console, i got this error
XHR POST http://127.0.0.1:8000/%7B%%20url%20%22home%22%20%%7D
I am unable to find, where is the issue.

You should use # for selecting id, so use text:$("#id_text").val().
For using dynamic url, use like this:
url:"{% url 'home' %}",
For more information, about using dynamic urls refer this question.
Edit:
One way to use dynamic url is to pass it with onsubmit event, so try this:
Template file or home.html
<form id="post-form" method="POST" onsubmit="checking('{% url 'home' %}')">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="submit" id="submit-button">
</form>
Js file:
function checking(dynamicUrl) {
$(document).on("submit", "#post-form", function (x) {
x.preventDefault();
console.log("button clicked");
$.ajax({
type: "POST",
url: dynamicUrl,
data: {
text: $("#id_text").val(),
csrfmiddlewaretoken: $("input[name=csrfmiddlewaretoken]").val(),
},
success: function () {
alert("Saved");
},
});
});
}

Related

How to get multiple ajax functions to work correctly

I have a django template with two forms in it. When the first form is submitted, an ajax function is triggered and the second form is displayed on the page. When the second form is submitted, the ajax function linked to that form does not seem to work.
For testing purposes, I tried to submit the second form before submitting the first form, and the ajax function works as expected. How do I make multiple ajax functions work correctly one after the other?
This is my template
<div class="form_container">
<div class="form">
<form action="{% url 'process_url' %}" method="post" id="youtube_link_form">
{% csrf_token %}
<div class="input-group mb-3">
<input type="text" class="form-control youtube_link_input"
placeholder="Put the youtube link or video id" aria-label="youtube_submit_input"
aria-describedby="youtube_submit_button" name="youtube_submit_input">
<button class="btn youtube_submit_button" type="submit" id="youtube_submit_button">Submit</button>
</div>
</form>
</div>
</div>
<div class="user_target_select">
<div class="target_buttons d-flex justify-content-between">
<form method="get" action="{% url 'user_select_positive' %}" id="positive_user_select_form">
<input type="hidden" id="positive_user_select_input" name="positive_user_select_input">
<button class="target_button btn btn-outline-success" id="user_select_positive" type="submit"
data-bs-toggle="modal" data-bs-target="#thank_model">Positive</button>
</form>
</div>
</div>
Here, user_target_select div is hidden by default. When the first form is submitted, the div is displayed.
This is my js file
function youtube_link_form_submit(event) {
event.preventDefault();
var data = new FormData($('#youtube_link_form').get(0));
$.ajax({
url: $(this).attr('action'),
type: $(this).attr('method'),
data: data,
cache: false,
processData: false,
contentType: false,
success: function (data) {
$('#status').append(data['status'])
$('.user_target_select').css('display', 'block');
if (data['status'] == 'video parsed successfully') {
console.log('data submitted successfully')
}
}
})
return false;
}
function positive_user_select_form_submit(event) {
event.preventDefault();
var data = $(this).serialize();
$.ajax({
url: $(this).attr('action'),
type: $(this).attr('method'),
data: data,
cache: false,
processData: false,
contentType: false,
success: function (data) {
console.log(data)
$('.user_target_select').css('display', 'none');
}
})
return false;
}
// trigger the above functions on form submit
$(function () {
$('#youtube_link_form').submit(youtube_link_form_submit);
})
$(function () {
$('#positive_user_select_form').submit(positive_user_select_form_submit);
})
Currently when the second form is submitted the ajax function is not called. I know this because the event.preventDefault() is not working and the JsonResponse from the django view is executed on a new page. The URL also changes. If I try to submit the second form without submitting the first form, the function works as expected.

How to use Ajax in Django for like button

I want to Ajax feature for the like button in my blog. I have implemented like feature first, it was working as expected(reloads page after clicking like button). Then, i want to implement Ajax so the page should not reload after clicking like button. But, it is not working as expected.
views.py:
def like_post(request):
user = request.user
if request.method == 'POST':
post_id = request.POST.get('id')
post_obj = get_object_or_404(Post, id=post_id)
if user in post_obj.liked.all():
post_obj.liked.remove(user)
else:
post_obj.liked.add(user)
like, created = Like.objects.get_or_create(user=user, post_id=post_id)
if not created:
if like.value == 'Like':
like.value = 'Unlike'
else:
like.value = 'Like'
like.save()
if request.is_ajax():
post = Post.objects.all()
context={
'post': post
}
html = render_to_string('blog/like_section.html', context, request=request)
return JsonResponse({'form': html})
Jquery in base.html:
<script src="https://code.jquery.com/jquery-3.1.1.min.js">
<script type="text/javascript">
$(document).ready(function(event){
$(document).on('click', '#like', function(event){
event.preventDefault();
console.log("hello")
var pk = $(this).attr('value');
$.ajax({
type : 'POST',
url : {% url 'like-post' %},
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>
like_section.html:
<form action="{% url 'like-post' %}" method="POST">
{% csrf_token %}
<input type="hidden" name="post_id" value="{{ post.id }}">
{% if user not in post.liked.all %}
<button id="like" class="btn btn-outline-info mb-4" type="submit">Like</button>
{% else %}
<button id="like" class="btn btn-info mb-4" type="submit">Unlike</button>
{% endif %}
</form>
urls.py:
path('likes/', views.like_post, name='like-post'),
It returns 404 with No Post matches the given query. My observation is, it looks it is not detecting Jquery part because if I replace 'id' with 'post_id' in request.POST.get('id') & return redirect under request.method == 'POST', it works like my previous version(Reloads page if I hit like button). So the control never goes into request.is_ajax() loop, How do I make Django to use Ajax?

How do I submit a form without page reload using Ajax

I'm learning Ajax on how I can submit a comment form without page reload. I'm using Django, I have list of posts in homepage each with comment form. When I submit a comment it is not saving in database and also it doesn't display in browser. When I check on Chrome console, I got an error 2 elements with non-unique id.
from django.http import JsonResponse
from django.template.loader import render_to_string
def home(request):
all_images = Post.objects.filter(poster_profile=request.user)
if request.method == 'POST':
post_id = request.POST.get("post_comment")
post_obj = Post.objects.get(pk=post_id)
form = CommentForm(request.POST)
if form.is_valid():
comment=form.save(commit=False)
comment.user=request.user
comment.commented_image=post_obj
comment.save()
else:
form=CommentForm()
context = {'all_images':all_images, 'form':form}
if request.is_ajax():
html=render_to_string('ajax_feeds_comment.html', context, request=request)
return render(request, 'home.html', context)
#home.html
{% for post in all_images %}
<img src="{{ post.image.url }}">
{% for comment in post.comments.all %}
<p>{{ comment.comment_post }}</p>
{% endfor %}
<div class="reload-form">
{% include "ajax_feeds_comments.html" %}
</div>
{% endfor %}
#ajax_feeds_comments.html
<form method="POST" class="feeds-comment" action=".">
{% csrf_token %}
<input type="hidden" value="{{post.id}}" name="post_comment">
<textarea name="comment_post" class="form-control" id="id_comment_post{{post.id}}"></textarea>
<button type="submit" class="btn btn-primary">submit</button>
</form>
<script>
$(document).on('submit', '.feeds-comment', function(event){
event.preventDefault();
console.log($(this).serialize());
$.ajax({
type: 'POST',
url: $(this).attr('action'),
data: $(this).serialize(),
dataType: 'json',
success: function(response){
$('.reload-form').html(response['form']);
},
error: function(rs, e) {
console.log(rs,responseText);
},
});
});
</script>
There are multiple things not correct here:
In your "urls.py" you should not send every request to your views. This is where you get the "favico.ico" error 500 get from. Having no favico is ok, but getting a Error 500 is not.
Check the html code for duplicate id's! These have to be unique.
If you use django variables for html, do it like this: Instead of "{{post.id}}" use: "{{ post.id }}" with spaces around the var.
In the
document.on("submit", "feeds-comment", function(){...})
you're not using the id of that element but it's class name.
Check where the submit is going to. Check Django if the request is being handled. (You see that in the console where Django is running). Also maybe Post a screenshot here!

How Can I send json file by ajax to django?

Can I send .json with data like (login,password from input html) to django who download this file and check login/password? Then I want return results by django to js,jquery. I dont wan use forms-django in form-html and dont want change urls.
code html:
<form id='login_form' action="" method="POST">
{% csrf_token %}
<div id='Login_form'>
<p>Login: </p> <input type="text" onblur="CheckEmptyElements();" id="flogin">
<p>Password: </p> <input type="password" onblur="CheckEmptyElements();" id="lpass">
<div id="butt_form">
<button type="button" class="butt_forme" id="button" onclick="CheckBeforeSend();">Enter</button>
</div>
</div>
</form>
code js:
var LoginInput = document.getElementById('flogin');
if(LoginInput.value.match(/^[a-zA-Z]+['.']+[a-zA-Z]+[0-9]+$/) == null)
{
if(document.getElementById('Windows').childElementCount > 2)
{
document.getElementById('Windows').children[0].remove();
}
AddPicture("paperJsConn");
}
else // <--- Check login/pass in base django
{
document.getElementById("button").type = "submit";
$.ajax({
type:"POST",
url: '',
data: {
"login":
"password":
},
success: function(response){
//animation and change site if correct login/pass or reloaded site.
}
});
}
and views.py:
def Logget(request):
if request.is_ajax and request.method == "POST":
//take login from json and check in base by loop
//if find check password
if: // correct
// return .json or message that is correct.
else:
// return .json or message that is not correct.
return render(request, 'index.html')
Someone help please?

NoReverseMatch error using django with ajax

I am trying to add ajax on the delete button of my blog, I want to update the page without reloading it when I delete an article, but I am getting this error when I use ajax and I don't understand what's going wrong.
Reverse for 'article_effacer' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['article/delete/(?P<slug>[-\\w\\d]+)/$']
I am turning myself to you because I'm having a hard time resolving this issue, so here is the code.
views.py
def article_effacer(request, slug):
if request.user.is_authenticated():
user = request.user
article = Article.objects.filter(slug=slug, user=user).delete()
context = {'article':article}
return HttpResponse(json.dumps(context), content_type='application/json')
else:
return HttpResponseForbidden()
urls.py
url(r'^delete/(?P<slug>[-\w\d]+)/$', views.article_effacer, name="article_effacer"),
template.html
<input class="delete" id="{{ a.slug }}" data-url='{% url "article.views.article_effacer" a.slug %}' value="Effacer">
Ajax
$('.delete').click(function(){
var slug = $(this).attr('id');
var url = $(this).data('url');
$.ajax({
type: "POST",
url: url,
data: {'slug': $(this).attr('id'), 'csrfmiddlewaretoken': '{{ csrf_token }}'},
dataType: "json",
success: function(response) {
console.log('deleted')
$(".article" + slug).remove();
},
error: function(rs, e) {
console.log(slug)
}
})
})
The problems comes probably from the url, but I don't understand how to correct it, any suggestions?
_ Update _
Full template
{% block content %}
{% for a in article %}
<div class="article{{a.slug}}">
[... unrelated html ...]
{% if a.user == user %} |
<input class="delete" id="{{ a.slug }}" data-url='{% url "article.views.article_effacer" a.slug %}' value="Effacer">
{% endif %}
</div>
{% endfor %}
{% endblock %}
{% block javascript %}
<script>
$('.delete').click(function(){
var slug = $(this).attr('id');
var url = $(this).data('url');
$.ajax({
type: "POST",
url: url,
data: {'slug': $(this).attr('id'), 'csrfmiddlewaretoken': '{{ csrf_token }}'},
dataType: "json",
success: function(response) {
console.log('deleted')
$(".article" + slug).remove();
},
error: function(rs, e) {
console.log(slug)
}
})
})
</script>
{% endblock %}
You can't use template tags like that, with values coming from JS; it should be clear that template tags are resolved on the server side, whereas the JS is executed on the client according to what the user clicks.
However you are halfway there by putting the value in the input. Actually, inputs don't have a href attribute, but you could use a data- prefix; the point is that you can then grab that in your JS to use as the URL. Something like:
<input class="delete" id="{{ a.slug }}" data-url='{% url "article.views.article_effacer" a.slug %}' value="Effacer">
var url = $(this).data('url');
$.ajax({
type: "POST",
url: url,
...
});

Categories