I'm using ajax in Django to activate add to favorites button, here are my files
urls
path('<int:pk>/favorite_item/', views.favorite_item, name='favorite_item'),
views.py
#login_required
def favorite_item (request, pk):
favitem = get_object_or_404(Item, pk=pk)
data = {
'is_fav': Favorite.objects.filter(user=request.user, item=favitem).exists(),
}
if data ['is_fav']:
Favorite.objects.get(user=request.user, item=favitem).delete()
else:
new_entry = Favorite.objects.create(item=favitem, user=request.user)
return JsonResponse(data)
finally HTML
only the part of the script
{% block javascript %}
<script>
$("#add_to_fav").click(function () {
console.log( $(this).val() );
});
$.ajax({
url: form.attr("data-favorite_item-url"),
data: form.serialize(),
dataType: 'json',
success: function (data) {
$('.results').html(data);
},
});
</script>
{% endblock %}
Now when I click the element that should trigger the whole action, the function is already working and the item is removed or added to db, but it takes me to another page which only has 1 sentence ({"is_fav": true}) or ({"is_fav": false})
You need to use preventDefault to stop your browser from actually going to the linked page when the link is clicked. You need to change lines 3 and 4 of the code you included like this:
{% block javascript %}
<script>
$("#add_to_fav").click(function (event) {
event.preventDefault();
console.log( $(this).val() );
});
$.ajax({
url: form.attr("data-favorite_item-url"),
data: form.serialize(),
dataType: 'json',
success: function (data) {
$('.results').html(data);
},
});
</script>
{% endblock %}
Related
When using POST request with AJAX in Django 4.0.1 I can't reach the file from the backend using request.FILES. The form used is pretty simple so I can't spot any typos etc.
HTML:
<form id="snipForm" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" id="multiFiles" name="files[]" multiple="multiple"/>
<button id="upload">Upload</button>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
JavaScript: (sorry for quite a long code sample but I can't shrink it more)
$(document).ready(function (e) {
$('#upload').on('click', function (event) {
//Prevent page from reloading
event.preventDefault()
var form_data = new FormData();
// check if there is any file selected
var ins = document.getElementById('multiFiles').files.length;
if(ins == 0) {
$('#msg').html('<span style="color:red">Select at least one file</span>');
return;
}
// add all files
for (var x = 0; x < ins; x++) {
form_data.append("files[]", document.getElementById('multiFiles').files[x]);
}
// obtain CSFR token
csrf_token = $('input[name="csrfmiddlewaretoken"]').val();
// set the headers
headers = {'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest', 'X-CSRFToken': csrf_token};
$.ajax({
type: 'POST',
url: '/docs/', // point to server-side URL
dataType: "json",
ContentType: "application/x-www-form-urlencoded",
cache: false,
processData: false,
headers: headers,
data: form_data,
success: function (response) { // display success response
console.log("successssssssssssss")
},
error: function (response) {
console.log("NOPEEEEEE")
}
});
});
});
views.py:
from django.views.decorators.csrf import ensure_csrf_cookie
#ensure_csrf_cookie
def generate(request):
is_ajax = request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
if request.method == 'POST' and is_ajax:
files = request.FILES.getlist('files[]')
if files:
print("file here")
#do some stuff
else:
print("NO FILE AT ALL")
return JsonResponse({...})
Request itself seems to be working console.log('sucessss') is visible after request is completed. Django however has no access to the file. The data with stored file is saved in the form_data but as far as I know we can reach files through mentioned request.FILES['name_of_the_input'].
What might be the cause?
When doing a file upload(with FormData) with $.ajax, you must set contentType and processData to false.
Otherwise jQuery will try to convert you FormData object to a string and set the content type of the request to "application/x-www-form-urlencoded" which is wrong.
The correct content type is multipart/formdata and will be set automatically.
$.ajax({
type: 'POST',
url: '/docs/', // point to server-side URL
dataType: "json",
cache: false,
contentType: false,
processData: false,
headers: headers,
data: form_data,
success: function (response) { // display success response
console.log("successssssssssssss")
},
error: function (response) {
console.log("NOPEEEEEE")
}
});
$("#feedlikes").on("click", function(e){
e.preventDefault();
$.ajax({
type: 'get',
url:'{% url "feedlikes" %}',
data:{},
success: function({
alert("Updated Successfully")
}),
}),
}),
those are my Ajax code help me to get them work.
this is my view:
def feedlikes(request, feed_id):
feed_update= Feeds.objects.get(pk=feed_id)
feed_update.likes = feed_update.likes +1
feed_update.save()
your feedlikes function expect feed_id but you are not supplying in the ajax url. Your ajax url should be
url:'{% url "feedlikes" feed_id=1 %}'
The problem: how to get that feed id in ajax?
You can make a hidden html tag with id equal to #feedlikes-id (eg feedlikes-1) inside #feedlike div or something like that and access just above submitting ajax and store in some variable and set to url then submit.
If you need to update the data you need to pass post method in ajax with csrf_token in headers.
$("#feedlikes").on("click", function(e){
e.preventDefault();
$.ajax({
type: 'post',
url:'{% url "feedlikes" %}',
data:{},
headers: {
'X-CSRF-Token': {{csrf_token}}
},
success: function({
alert("Updated Successfully")
}),
}),
}),
I am trying to delete some elements in database when user clicks on delete icon but as i am sending id through POST request , i am getting empty dictionary ,
{% for skills in seeker_skills %}
<div class="col-md-4">
<button class="btn btn-info mx-2">{{skills.skill_name}}<span class="badge badge-dark ">{{skills.skill_level}}</span></button><span><i class="fas fa-trash-alt delete_skill" data-attr={{skills.id}} style="cursor: pointer;"></i></span>
</div>
{% endfor %}
updated snippet , i am calling it on click
Ajax code
let delete_class_list = $('.delete_skill')
delete_class_list.click(function(e){
let value = this.getAttribute("data-attr")
let contain_icon = this
let contain_label = contain_icon.parentElement.previousSibling
console.log(contain_label)
$.ajax({
url:'/delete_skill/',
method : 'POST',
data: {
skill_id:value
},
dataType: "json",
contentType: "application/json",
success :function(data){
console.log(data)
contain_label.remove()
contain_icon.remove()
}
,
error:function(e){
console.log(e)
}
})
})
My view
#csrf_exempt
def delete_skill(request):
if request.method == 'POST':
data = {}
print('method is post')
job_id = request.POST.get('skill_id')
print(job_id)
try:
Job_Skillset.objects.get(id=job_id).delete()
data['status'] = 'deleted'
except ObjectDoesNotExist:
data['status'] = 'nodata'
return JsonResponse(data,safe=False)
You're setting your content type to application/json which is incorrect, remove it.
$.ajax({
url:'/delete_skill/',
method : 'POST',
data: {
skill_id:value
},
dataType: "json",
success :function(data){
console.log(data)
contain_label.remove()
contain_icon.remove()
}
,
error:function(e){
console.log(e)
}
})
I want to display the content of an announcement inside a modal when a user clicked on the announcement list.
This will be the trigger for the modal in my announcement_list.html:
<form name="form" action="#" id="form_have_product_{{y.id}}" method="POST">
{% csrf_token %}
View
</form>
This is my function in my views.py:
def get_announcement(request, pk):
announcement = Announcement.objects.filter(announcement_id=pk)
context = {
'title': announcement.title,
'about': announcement.about,
'author': announcement.author,
'post_date': announcement.post_date
}
return render(request, 'announcement-details-modal.html', context)
For the urls.py:
urlpatterns = [path('announcement/<int:pk>/', get_announcement, name='announcement-detail'),]
And this is the function for when the user clicks on the announcement list:
$(".view-announcement").on("click", function() {
var target_url = $(this).attr("data-url");
var csrftoken = $("[name=csrfmiddlewaretoken]").val();
$.ajax({
url: target_url,
headers:{
"X-CSRFToken": csrftoken
},
success: function(data) {
$("#modal").modal("toggle");
$("#modal-content").html(data);
}
});
});
Currently this code returns the server responded with a status of 500 (Internal Server Error)
Consider a textarea input to enter emails.
The view has a forloop: for each email the view tries to create a user. Then, if the user is created, I append it to my array "newUers", if the user already exists, I append it to the "alreadyUsers" array.
When the loop ends, I want to render a view with these arrays. But it does not work...
The users are correctly created but the view does not render the template.
Any idea?
invitations.html: a textarea with an an ajax call on submit
<div id="invitations">
<label>Enter your clients email</label>
<textarea v-model="invitations" class="textarea" id="invitations" name="invitations"></textarea>
</div>
<div>
<input id="send" type="submit" value="Save" #click="submit()">
</div>
user_invitation.js: the ajax call (based on Vue)
var vue = new Vue({
el: '#invitations',
data: {
invitations: '',
},
methods: {
submit: function () {
var self = this;
$.ajax({
type: 'POST',
url: '/accounts/invitations/create/',
data: {
invitations: this.invitations,
csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
},
context: this,
success: function () {
console.log("ajax success");
},
error: function () {
console.log("ajax error");
}
})
}
}
});
views.py
def InvitationCreateView(request):
newUsers = []
alreadyUsers = []
for client in request.POST['invitations'].split('\n'):
try:
# Get informations for creating the User
user = User.objects.create(
username=client,
email=client,
)
user.groups.add(Group.objects.get(name='Clients'))
user.save()
newUsers.append(client)
# Check if user already exists
except IntegrityError:
alreadyUsers.append(client)
return render(request, 'accounts/agent_invitations_confirmation.html',
{"newUsers": newUsers, "alreadyUsers": alreadyUsers})