Ajax post data don't arrive to Django - django

I am developing a Django application. I am trying using jquery and ajax for a POST request but I am not able to find the error.
I am basically struggling to send the data from the frontend with ajax to the server.
views.py
def add_new_question_feedback(request, pk):
if request.headers.get('x-requested-with') == 'XMLHttpRequest':
question = Question.objects.get(id=pk)
feedback = QuestionFeedback(
question=question, user=request.user, text=request.POST.get('feedback'), feedback_choice=request.POST.get('feedback_choice'))
feedback.save()
feedback = serializers.serialize('json', [feedback])
return HttpResponse(feedback, content_type='application/json')
models.py
class QuestionFeedback(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
user = models.ForeignKey('users.CustomUser', on_delete=models.CASCADE)
text = models.TextField()
feedback_choice = models.CharField(
max_length=200)
is_closed = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
template
<div class="modal-header">
<h5 class="modal-title">${gettext(
"Question Feedback"
)} n° ${res[0].pk}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="form-group mt-3">
<label class="form-label">${gettext(
"Feedback Type"
)}</label>
<select name="feedback_choice" id="feedback_choice" class="form-control" required="">
<option value="" selected="" disabled>${gettext(
"Select Topic"
)}</option>
<option value="Wrong Question">${gettext(
"Wrong Question"
)}</option>
<option value="Wrong Answer">${gettext(
"Wrong Answer"
)}</option>
<option value="Other">${gettext(
"Other"
)}</option>
</select>
</div>
<div class="form-group mt-3">
<label class="form-label">${gettext(
"Feedback"
)}</label>
<textarea name="feedback" id="feedback" rows="10" class="form-control"></textarea>
</div>
<button type="button" class="btn btn-success mt-3" id="addFeedback"> ${gettext(
"Add New Feedback"
)} </button>
<button type="button" class="btn btn-danger mt-3 ms-3" data-bs-dismiss="modal">${gettext(
"Close"
)}</button>
</div>
`;
ajax function
$("#addFeedback").on("click", function () {
$.ajax({
type: "POST",
url: "/quiz/add_new_question_feedback/" + questionBtnId,
data: {
feedback_choice: $("#feedback_choice").find(":selected").text(), //I can't post feedback_choice to the server
feedback: $("textarea#feedback").val(), //I can't post feedback to the server
csrfmiddlewaretoken: csrftoken,
},
success: function (response) {
$("#feedbackModal").modal("hide");
handleAlerts(
"success",
gettext("New Question Feedback sent successfully!")
);
},
error: function (error) {
$("#feedbackModal").modal("hide");
handleAlerts("danger", gettext("Oops, something went wrong!"));
},
});
});
My proble is that basically feedback and feedback_choice are not sent to the serve. I know that something is wrong inside my ajax data variable, but I don't know how to solve it.

The header for XMLHttpRequest is case sensitive. X-Requested-With
def add_new_question_feedback(request, pk):
if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
question = Question.objects.get(id=pk)
feedback = QuestionFeedback(
question=question, user=request.user, text=request.POST.get('feedback'), feedback_choice=request.POST.get('feedback_choice'))
feedback.save()
feedback = serializers.serialize('json', [feedback])
return HttpResponse(feedback, content_type='application/json')

Related

I wanted to craete a 5 star rating system in django but it keeps getting this error:

i check with django document and But my problem was not solved
[08/Feb/2023 15:57:18] "POST /courses/2/learning-django HTTP/1.1" 403 2506
error:
Forbidden (CSRF token missing.): /courses/2/learning-django
this is my models
class Review(models.Model):
course = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='reviews')
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
rating = models.IntegerField(null=True, validators=[MinValueValidator(1), MaxValueValidator(5)])
comment = models.TextField()
created = models.DateField(auto_now_add=True)
active = models.BooleanField(default=False)
def __str__(self):
return f'{self.first_name} {self.last_name}
my views:
def productDetailView(request, id, slug):
product = get_object_or_404(Product, id=id, slug=slug, available=True)
new_comment = None
if request.method == 'POST':
form = ReviewForm(request.POST)
if form.is_valid():
new_comment = form.save(commit=False)
new_comment.course = product
new_comment.rating = request.POST['rating']
new_comment.save()
else:
form = ReviewForm()
return render(request, 'shop/product_detail.html', {'product': product, 'form': form})
js function:
$(document).ready(function(){
$('.rate .rate-item').on('click', function(){
var value = $(this).data('value');
$.ajax({
url: '{{ product.get_absolute_url }}',
type: 'POST',
data: {'rating': value},
success: function(response){
alert('Rating saved successfully!');
}
});
});
});
my template
<form method="post">
<div class="row">
<div class="col-md-6">
<div class="form-singel">
{{ form.first_name|attr:" placeholder:Fast name" }}
</div>
</div>
<div class="col-md-6">
<div class="form-singel">
{{ form.first_name|attr:" placeholder:Last Name"}}
</div>
</div>
<div class="col-lg-12">
<div class="form-singel">
<div class="rate-wrapper">
<div class="rate-label">Your Rating:</div>
<div class="rate">
<div data-value="1" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div>
<div data-value="2" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div>
<div data-value="3" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div>
<div data-value="4" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div>
<div data-value="5" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div>
</div>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="form-singel">
{{ form.first_name|attr:" placeholder:Comment" }}
</div>
</div>
{% csrf_token %}
<div class="col-lg-12">
<div class="form-singel">
<button type="submit" class="main-btn">Post Comment</button>
</div>
</div>
</div> <!-- row -->
</form>
I used csrf_token in my form but it seems that dosen't work
and i searched in stackoverflow no one have same error
how do i fix it
If you want to make AJAX request, you need to add CSRF token to the data body.
$.ajax({
url: '{{ product.get_absolute_url }}',
type: 'POST',
data: {'rating': value, csrfmiddlewaretoken: '{{ csrf_token }}'},
success: function(response){
alert('Rating saved successfully!');
}
});
Original answer: https://stackoverflow.com/a/6170377/5711733
Basically what you miss is csrftoken in the form data.
You have two possibilities:
Either define view with #csrf_exempt:
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def productDetailView(request, id, slug):
product = get_object_or_404(Product, id=id, slug=slug, available=True)
new_comment = None
Or load variable from cookie and pass it into headers (I'm using js-cookie library but you can find single functions on stack overflow that will fit your needs) - example:
$.ajax({
url: url,
type: 'POST',
headers: {
'X-CSRFTOKEN': Cookies.get('csrftoken'),
},
success: (data) => {
location.reload();
}
})
From what I know first solution should be more secure.

I am trying to get POST request but django response with GET request

I am trying to get the post request and i have tried everything it is still getting me get requests.
Please Help.
I have tried using that i saw in other problems displayed here. but it is not working for me.
{% csrf_token%}
Item name
{{form.item_name}}
Quantity
{{form.quantity}}
<div class="form-group">
<label for="address">Address</label>
{{form.address}}
</div>
<div class="modal-footer d-flex justify-content-center">
<button type="submit" id="submit" class="btn btn-success" data-dismiss="modal" >Donate</button>
</div>
</form>
This is my view file
#this is my view
#login_required(login_url='loginPage')
def home(request):
form = DonateForm()
print(request.user.id)
get_user = user_info.objects.get(id=request.user.id)
print('Inside Home View')
print(get_user)
print(request)
if request.method == 'POST':
form = DonateForm(request.POST)
print('Inside Home Page')
if form.is_valid():
print('Form is valid!!')
user = form.save()
Donate.objects.create(user_name = user,item_name=form.cleaned_data['item'],quantity=form.cleaned_data['itemquantity'])
else:
messages.add_message(request,messages.INFO,'Your details are Incorrect!!')
else:
print('No Post Request!!')
return render(request,'donate/home.html',{'form':form,'get_user':get_user})
Here is my Models.py
class Donate(models.Model):
user_name = models.ForeignKey(user_info,on_delete=models.CASCADE)
item_name = models.CharField(max_length=30,null=False , blank=False, default ="None")
quantity = models.IntegerField(null=False,blank=False,default=0)
address = models.CharField(max_length=100 , null=False , blank= False, default="None")
def __str__(self):
return f"{self.user_name.user.username} donated {self.item_name}"
Please try to add the method in the <form>, like this:
<form method="post" action="#">
{% csrf_token %}
......
<button type="submit" id="submit" class="btn btn-success" data-dismiss="modal" >Donate</button>
</form>

Simple Django Form with Ajax Submission Not Updating Model

I'm trying to write a simple form using Ajax. After multiple attempts, I keep getting "POST /app/emails/ HTTP/1.1" 200 13950 in Terminal, but the model doesn't update (even when I look in the shell).
I really would like the abilityt to submit the form within the modal, and update the image behind it. However if that's not possible I can settle for an alternative.
Really stuck here, would love any advice!
emails.html
<div class="modal fade" id="addEmailModal" data-bs-backdrop="static" data-bs-keyboard="false"
tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-sm">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Add New Email</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<form method="POST" id='add-email'>
{% csrf_token %}
<fieldset class="form-group">
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close
</button>
<button class="btn btn-primary" type="submit">Add</button>
</div>
</form>
</div>
</div>
</div>
Javascript
$("#add-email").submit(function (e) {
e.preventDefault();
alert('working');
$.ajax({
type: 'POST',
url: "{% url 'add-emailname' %}",
data: {
email_name = $(this).email_name,
cadence = $(this).cadence
},
success: function (response) {
alert("Email name successfully added!")
$("#add-email").trigger('reset'); //clear the form
},
error: function (response) {
// alert the error if any error occured
alert(response["responseJSON"]["error"]);
}
})
}
views.py
def emails(request):
context = {
'emails': UserEmail.objects.all(),
'form': EmailCreateForm()
}
return render(request, 'app/emails.html', context)
def addEmailName(request):
if request.is_ajax and request.method == "POST":
form = EmailCreateForm(request.POST)
if form.is_valid():
form.save()
returned_email_name = form.cleaned_data.get('email_name')
messages.success(request, f'{returned_email_name} added as new Email!')
# send to client side.
return JsonResponse({"success": True}, status=200)
else:
# some form errors occured.
return JsonResponse({"error": form.errors}, status=400)
# some error occured
return JsonResponse({"error": ""}, status=400)
forms.py
class EmailCreateForm(ModelForm):
class Meta:
model = UserEmail
fields = ['email_name', 'cadence']
def __init__(self, *args, **kwargs):
super(EmailCreateForm, self).__init__(*args, **kwargs) # Call to ModelForm constructor
self.fields['email_name'].widget.attrs['rows'] = 1
self.fields['cadence'].widget.attrs['rows'] = 1
urls.py
urlpatterns = [
path('', views.home, name='app-home'),
path('emails/', views.emails, name='app-emails'),
path('post/ajax/addEmailName', addEmailName, name='add-emailname')]

Error When submit comment for the second post in Django

I creating a blog in this blog feed there are posts and for each post there are comments, So my problem when I submit a comment for the first post is submitting successfully but when I try to submit a comment for the second post or third it doesn't submit
My comments Form
class PostCommentForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class Meta:
model = PostCommentIDF
fields = {'post', 'content'}
widgets = {
'content': forms.Textarea(attrs={'class': 'rounded-0 form-control', 'rows': '1', 'placeholder': 'Comment', 'required': 'True', })
}
def save(self, *args, **kwargs):
PostCommentIDF.objects.rebuild()
return super(PostCommentForm, self).save(*args, **kwargs)
My comments view
#login_required
def add_comment_post(request):
if request.method == 'POST':
if request.POST.get('action') == 'delete':
id = request.POST.get('nodeid')
c = PostCommentIDF.objects.get(id=id)
c.delete()
return JsonResponse({'remove': id})
else:
comment_form = PostCommentForm(request.POST )
if comment_form.is_valid():
user_comment = comment_form.save(commit=False)
user_comment.author = request.user
user_comment.save()
result = comment_form.cleaned_data.get('content')
user = request.user.username
return JsonResponse({'result': result, 'user': user})
return JsonResponse({'result': "No action took"})
My comment form in home page template
<form id="Postcommentform" class="Postcommentform" method="post" style="width: 100%;">
{% load mptt_tags %}
{% csrf_token %}
<select class="d-none" name="post" id="id_post">
<option value="{{ video.id }}" selected="{{ video.id }}"></option>
</select>
<div class="d-flex">
<label class="small font-weight-bold">{{ comments.parent.label }}</label>
{{ comments.parent }}
{{comments.content}}
<button value="Postcommentform" id="Postnewcomment" type="submit" style="color: white; border-radius: 0;" class="d-flex justify-content-end btn btn-primary">Post</button>
</div>
</form>
Update
My comment Model
class PostCommentIDF(MPTTModel):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')
author = models.ForeignKey(Account, on_delete=models.CASCADE)
content = models.TextField()
publish = models.DateTimeField(auto_now_add=True)
Post Model
class Post(models.Model):
author = models.ForeignKey(Account, on_delete=models.CASCADE)
article = models.TextField(null=True, blank=True)
photo_article = models.ImageField(max_length=255, upload_to=get_poster_filepath)
created_date = models.DateTimeField(auto_now_add=True)
I use Ajax for submet the comment, When I submit comment for first post this shows {result: "comment", user: "user1"} but when I submit comment for any diffrent post except the first one this shows {result: "No action took"}
How I can let the user submit comment to any post not just for the first one
Edit
myCommentForm = document.getElementById("Postcommentform")
$(document).on('click', '#Postnewcomment, #Postnewcommentinner', function (e) {
e.preventDefault();
var button = $(this).attr("value");
var placement = "Postcommentform"
if (button == "Postnewcommentform") {
var placement = "becomm"
}
$.ajax({
type: 'POST',
url: '{% url "video:addcomment_post" %}',
data: $("#" + button).serialize(),
cache: false,
success: function (json) {
console.log(json);
$('<div id="" class=" p-2" style=""> \
<div class="d-flex bd-highlight mb-3">\
<div class="p-2 bd-highlight"><img src="{{request.user.profile_image.url}}" alt="" class="rounded-circle bd-highlight" width="30" height="30"> ' + json['user'] + '</div> <div class="ml-auto p-2 bd-highlight">Posted: Just now!</div> \
</div>\
<div>' + json['result'] + '</div> \
</div>'
).insertAfter('#Boo');
document.getElementById("Postcommentform").reset();
},
error: function (xhr, errmsg, err) {
}
});
})
function myFunction(id) {
if (document.contains(document.getElementById("Postnewcommentform"))) {
document.getElementById("Postnewcommentform").remove();
}
var a = document.getElementById(id);
a.insertAdjacentHTML('afterend',
'<form id="Postnewcommentform" class="Postnewcommentform py-2" method="post"> \
{% csrf_token %}\
<div class="d-flex justify-content-between"><h2>Reply:</h2><div><button type="button" class="btn btn-outline-secondary" onclick="formExit()"">Close</button></div></div> \
<select name="parent" class="d-none" id="id_parent"> \
<option value="' + id + '" selected="' + id + '"></option> \
</select> \
<label id="id_content" required="" for="id_content">Content:</label> \
<textarea name="content" cols="40" rows="5" class="form-control" required="" id="id_content"></textarea> \
{% csrf_token %} \
<button type="submit" value="Postnewcommentform" id="Postnewcommentinner" class="btn btn-primary btn-lg btn-block">Submit</button> \
</form>');
}

Python(Django) :I want the payment form(code) triggered whenever a user clicks the submit button and only saved into DB if payment is succesful

I am currently using DJANGO
How can I make the payment form(code) triggered when a user clickn submit and also make it saved into DB after successful payment. Please help me out.. i have been trying to solved this days back.
Here is my models.py
from django.db import models
class Promoting(models.Model):
yourname= models.CharField(max_length=60)
fathername= models.CharField(max_length=60)
mothername= models.CharField(max_length=60)
imagefield=models.ImageField(upload_to='postedimages')
def __str__(self):
return self.promoterauthor
Here is my views.py
from django.shortcuts import render
from .models import Promoting
def homepage(request):
if request.method == 'POST':
yourname=request.POST.get('yourname')
fathername=request.POST.get('fathername')
mothername=request.POST.get(' mothername')
imagefield=request.FILES['imagefield']
newdata=Promoting(promoterauthor=promoterauthor,websiteurl=websiteurl,tagline=tagline,imagefield=imagefield)
newone.save()
return render(request, 'success.html', {})
else:
return render(request, 'homepage.html', {})
Here is my form
<form action="{% url 'home' %}" method="POST" role="form" enctype="multipart/form-data class="contactForm">
{% csrf_token %}
<div class="form-row">
<div class="form-group col-md-6">
<input type="text" name="yourname" id="yourname" class="form-control" placeholder="Youur username" required>
</div>
<div class="form-group col-md-6">
<input type="" class="form-control" name="fathername" id="fathername" placeholder="Your Website" required>
</div>
</div>
<div class="form-group">
<input type="text" class="form-control" name="mothername" id="mothername" placeholder="Add a Tag line" required>
</div>
<div class="form-group">
<input type="file" class="form-control" name="imagefield" id="imagefield" placeholder="Your image" accept="image/*" required>
</div>
<div class="text-center"><button type="submit">Send Message</button></div>
</form>
The form submits successfully into the database and also my payment gateway(Rave by flutterwave.COM is working well)n I ONLY NEED A WAY TO LINK BOTH TOGETHER
Precisely, what I want is the payment form triggered once the submit button is clicked and I only want a the data saved into DB if only payment is successful .. please help out
The code snippet from my payment gateway also works when the pay button is clicked...
Here it the payment code
<form>
<script src="https://api.ravepay.co/flwv3-pug/getpaidx/api/flwpbf-inline.js"></script>
<button type="button" onClick="payWithRave()">Pay Now</button>
</form>
<script>
const API_publicKey = "FLWPUBK-152e7e9e17c0f7e985f9fee5838eafcc-X";
function payWithRave() {
var x = getpaidSetup({
PBFPubKey: API_publicKey,
customer_email: "user#example.com",
amount:5,
customer_phone: "234099940409",
currency: "USD",
txref: "rave-123456",
meta: [{
metaname: "flightID",
metavalue: "AP1234"
}],
onclose: function() {},
callback: function(response) {
var txref = response.tx.txRef; // collect txRef returned and pass to a server page to complete status check.
console.log("This is the response returned after a charge", response);
if (
response.tx.chargeResponseCode == "00" ||
response.tx.chargeResponseCode == "0"
) {
// redirect to a success page
} else {
// redirect to a failure page.
}
x.close(); // use this to close the modal immediately after payment.
}
});
}
</script>
THIS IS WHAT IS GENERATED BY THE PAYMENT CODE WHEN PAY IS CLICKED