Django Ajax 405 (Method Not Allowed) CBV - javascript

I'm having trouble in POST-ing and DELETE-ing through Ajax call !
I've defined the methods on class! idk what is happening.
Any help will be appreciated 😀
urls.py:
path('<section>/add_wish/<slug>/', views.AddToWishlistView.as_view(), name='add_to_cart'),
my view :
class AddToWishlistView(LoginRequiredMixin, View):
model = Wishlist
http_method_names = ['POST']
def POST(self, request, *args, **kwargs):
wished_product = get_object_or_404(Product, slug=self.kwargs['slug'])
new_item = self.model.objects.get(customer = self.request.user)
new_item.product.add(wished_product)
return HttpResponse(status=201)
and Ajax here !
$('.buy').click(function(e){
e.preventDefault();
let _this = $(this);
var slug = _this.children().data('id');
var section_slug = _this.data('section');
$.ajax({
type : 'POST',
url : '../'+section_slug + '/add_wish/' + slug + '/',
success: function(data){
if(data.success = true){
_this.addClass('clicked');
}
},
async : false,
error : function(data){
console.log("ERROR");
console.log(data);
alert('LOOSERR');
}
})
});

The method name should be the lower case:
def post(self, request, *args, **kwargs):
Every request coming to the view goes thru the dispatch method which is responsible for calling the correct method. Here is explained how it works:
https://docs.djangoproject.com/en/3.0/ref/class-based-views/base/#django.views.generic.base.View.dispatch
and here is the source code:
https://github.com/django/django/blob/291539a85c8461456ab728fe6820a86de54294b6/django/views/generic/base.py#L93-L101

Related

How to call Django API with Javascript with Authenticated user in Django

I'm using Django for Backend, PostgresSQL as DB and HTML, CSS and Javascript as Frontend. I am calling Django API via Javascript. Where user is adding a product to a cart, and I'm calling the cart with DRF to show all the data to the user. But problem is that, user can see all the data of other user. So, how can authenticated user can see his/her selected product on a cart.
Here is a detailed code:
views.py
adding product to cart
def addProduct(request):
user = request.user
product_id = request.GET.get('product_id')
product_cart = Product.objects.get(id=product_id)
Cart(user=user, product=product_cart).save()
return render(request, 'cart/addtocart.html')
Api View (views.py)
#api_view(['GET'])
def showproduct(request):
if request.method == 'GET':
result = Cart.objects.all()
serialize = productserializers(result, many = True)
return Response(serialize.data)
serializer.py
from .models import *
from rest_framework import serializers
class productserializers(serializers.ModelSerializer):
class Meta:
model = Cart
fields = '__all__'
depth = 1
Javascript to call Django API
$(document).ready(function() {
$.ajax({
url: 'http://127.0.0.1:8000/showproduct/',
dataType: 'JSON',
success: function(data){
for (var i = 0; i < data.length; i++)
{
var row =
$('<tr> .. ..........</tr>');
$("#table").append(row);
}
}
});
});
NOW, How to show the specific user(authenticated user) there specific cart item.
you have to pass user id when you are calling ajax.
If you are using GETmethod than pass user id in URL and access it via argument in your view for eg.
$(document).ready(function() {
$.ajax({
url: '{% url "showdata" %}',
dataType: 'JSON',
success: function(data){
for (var i = 0; i < data.length; i++)
{
var row =
$('<tr> .. ..........</tr>');
$("#table").append(row);
}
}
});
});
and in your views.py
#api_view(['GET'])
def showproduct(request):
if request.method == 'GET':
result = Cart.objects.filter(user=request.user)
serialize = productserializers(result, many = True)
return Response(serialize.data)
and add this in your urls.py
urlpatterns = [
path("showdata/", views.showproduct, name='showdata')
]
UPDATE
there is no need to pass user id in ajax URL if user is authenticated than user will come in request
so please change you views.py, urls.py and ajax URL.

Django template variables with ajax

How to update Django for loop template variable using response data on Ajax success. The status of the object is updating in the database I just can't get it to update the template. if I remove + response.applicant_pk the template is updated but always just the first item in the for loop
<div id="app_status_" class="_button__base_ _blue__button">
<strong>{{applicant.status}}</strong>
</div>
def applicant_status_change(request, applicant_id):
response_data = {}
if request.method =='POST' and request.is_ajax():
try:
applicant = Applicant.objects.get(pk=applicant_id)
position = applicant.applied_for.id
position = Position.objects.get(id=position)
count = position.get_all_applied_users_count()
applicant.status = request.POST['applicant_status']
applicant.pk = request.POST['pk']
response_data = {
"applicant_status": applicant.status,
"applicant_pk":applicant.pk
}
applicant.save()
return JsonResponse(response_data)
except Applicant.DoesNotExist:
return JsonResponse({'status':'Fail', 'msg': 'Object does not exist'})
else:
return JsonResponse({'status':'Fail', 'msg':'Not a valid request'})
$(".dropdown-item").click(function (e) {
var applicant_stat = $(this).text();
var pk = "{{ applicant.pk }}"
$.ajax({
url : '/dashboard/applicant/status/{{ applicant.pk }}/',
type : "POST",
data : {
'csrfmiddlewaretoken' : "{{ csrf_token }}",
'applicant_status': applicant_stat,
'pk': pk
},
success: function(response) {
$('#app_status_'+ response.applicant_pk).empty().append(response.applicant_status);
},
});
});
if it helps anyone else: I hadn't added the applicant pk to the div ID
<div id="app_status_{{applicant.pk}}" data-pid="{{ applicant.pk }}" class="_button__base_ _blue__button">{{applicant.status}}
</div>

Django CRUD Ajax

I am building an application where I want users to be able to create posts. However, when I added the functionalities nothing happens after creating the 'Post' button, I can see that Django is not getting the url in the console.
Here is my Ajax code for Creating, Updating and Removing, the Update and remove work fine however the create is not working.
$(document).ready(function(){
var ShowForm = function(){
var btn = $(this);
$.ajax({
url: btn.attr("data-url"),
type: 'get',
dataType:'json',
beforeSend: function(){
$('#modal-post').modal('show');
},
success: function(data){
$('#modal-post .modal-content').html(data.html_form);
}
});
};
var SaveForm = function(){
var form = $(this);
$.ajax({
url: form.attr('data-url'),
data: form.serialize(),
type: form.attr('method'),
dataType: 'json',
success: function(data){
if(data.form_is_valid){
$('#post-list div').html(data.posts);
$('#modal-post').modal('hide');
} else {
$('#modal-post .modal-content').html(data.html_form)
}
}
})
return false;
}
// create
$(".show-form-create").click(ShowForm);
$("#modal-post").on("submit",".create-form",SaveForm);
//update
$('#post-list').on("click",".show-form-update",ShowForm);
$('#modal-post').on("submit",".update-form",SaveForm)
//delete
$('#post-list').on("click",".show-form-delete",ShowForm);
$('#modal-post').on("submit",".delete-form",SaveForm)
});
This is my views.py:
#login_required
def save_all(request,form,template_name):
data = dict()
if request.method == 'POST':
if form.is_valid():
form.save()
data['form_is_valid'] = True
posts = Post.objects.all()
data['posts'] = render_to_string('home/home_post.html',{'posts':posts})
else:
data['form_is_valid'] = False
context = {
'form':form
}
data['html_form'] = render_to_string(template_name,context,request=request)
return JsonResponse(data)
#login_required
def post_create(request):
if request.method == 'POST':
form = PostForm(request.POST)
else:
form = PostForm()
return save_all(request, form, 'home/post_create.html')
And this is the button I use:
<button class="btn btn-sm btn-primary show-form-create ml-auto" data-url="{% url 'home:post-create' %}">Post</button>
When I change the show-form-create to show-form-delete the PostForm pops up however when I change it back it seems not to be working. I have been on this issue for a while I cannot find what is causing the issue.
This is also available in my urls.py:
path('post/create/', views.post_create, name='post-create'),
I appreciate all the help in advance!

like button not doing anything, cant tell what the problem is

I want users to be able to like my post so I implemented here. here's my code. It doesn't give any error which is frustrating.
models.py
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField(blank=True, null=True)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
url = models.URLField(max_length=250, blank=True, null=True)
views = models.IntegerField(default=0)
likes = models.ManyToManyField(User, related_name='likes')
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
def total_likes(self):
return self.likes.count()
views.py
def like(request):
if request.method == 'POST':
user = request.user # bring login user
post_pk = request.POST.get('pk', None)
post = Post.objects.get(pk = post_pk) #bring the post object.
if post.likes.filter(id = user.id).exists(): #if exit
post.likes.remove(user) #likes deleted.
message = 'You disliked this'
else:
post.likes.add(user)
message = 'You liked this'
context = {'likes_count' : post.total_likes, 'message' : message}
return HttpResponse(json.dumps(context), content_type='application/json')
urls.py
urlpatterns = [
path('', PostListView.as_view(), name='community-home'),
path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail'),
path('post/<int:post_pk>/comment/new',views.comment_new, name='comment_new'),
path('post/<int:post_pk>/comment/<int:pk>/edit',views.comment_edit, name='comment_edit'),
path('post/<int:post_pk>/comment/<int:pk>/delete',views.comment_delete, name='comment_delete'),
path('like/', views.like, name='like'),
my html
<input type="button" class="like" name="{{ memo.id }}" value="Like">
<p id="count{{ memo.id }}">count : {{ memo.total_likes }}</p>
<script type="text/javascript">
for(i = 0; i < $(".writer_name").length; i++){
if($("#user_name").text() == $(".writer_name")[i].innerHTML){
$("#control_id"+i).removeClass("hidden");
}
}
$('.like').click(function(){
var pk = $(this).attr('name')
$.ajax({
type: "POST",
url: "{% url 'like' %}",
data: {'pk': pk, 'csrfmiddlewaretoken': '{{ csrf_token }}'},
dataType: "json",
success: function(response){
id = $(this).attr('name')
$('#count'+ pk).html("count : "+ response.likes_count);
alert(response.message);
alert("likes :" + response.likes_count);
},
error:function(request,status,error){
alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
}
});
})
</script>
I'm not sure if my ajax is wrong or my python is wrong. but to me the logic here makes sense. if anyone can tell what the problem is I would be really appreciated. Thanks
You are using jquery, before using it you must wrap code inside:
$(document).ready(()=>{
...
});
def like(request):
response_json = request.POST
response_json = json.dumps(response_json)
data = json.loads(response_json)
post = Post.objects.get(pk =data['pk'])
if post.likes.filter(id = user.id).exists(): #if exit
post.likes.remove(user) #likes deleted.
message = 'You disliked this'
else:
post.likes.add(user)
message = 'You liked this'
context = {'likes_count' : post.total_likes, 'message' : message}
return JsonResponse(context, safe=False)
try like this. You are sending a JSON datatype so python has to interpret it as so.

Ajax POST not sending data when calling 'request.POST' in Django view

I am attempting to get an Ajax POST to to send data to my view so I can manipulate my data there, when I click on a div with class up-arrow.
Problem is, when I click said div and print request.POST in my view file, I am getting a POST object that contains <QueryDict: {}>. Empty! I can't seem to figure out why my the POST request isn't sending my data through.
Here is my HTML...
{% for i in post.posts %}
<li>
<div>
<div class='up-arrow'>
</div>
{{i}}
</div>
</li>
{% endfor %}
Here is my AJAX/jQuery...
$(document).ready(function(){
$('.up-arrow').click(function(){
$(this).hide()
console.log('click')
$.ajax({
headers: {
'Content-Type':'application/json',
'X-CSRFToken': getCookie('csrftoken')
},
url: 'voteuppost',
type: 'POST',
data: {'dane': 123456789101112},
success: function(data) {
alert('success!')
},
error: function(){
alert('fail')
}
})
return false
});
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
})
Here is my view...
class VoteUpPost(View):
def post(self, request):
print(request.POST)
return JsonResponse({'status': True})
Here is my url route...
url(r'^voteuppost$', VoteUpPost.as_view()),
Things I have tried...
1) I used GET instead of POST and I am able to get the data value using request.GET.get('dane')
1) Tried using request.POST.data and request.POST.DATA and get the following... AttributeError: 'QueryDict' object has no attribute 'data'
and I also get a 'fail' alert.
How do I send my data over to my view via a POST request and then access the data within?
When posting JSON data with application/json you need to use request.body instead of request.POST.
Like so:
class VoteUpPost(View):
def post(self, request):
print(request.body)
data = json.loads(request.body)
return JsonResponse({'status': True})
Also as Jacques mentioned, make sure to update your js to pass a JSON string.
Change:
data: {'dane': 123456789101112},
To:
data: JSON.stringify({'dane': 123456789101112}),
Django request can only parse application/x-www-form-urlencoded and
multipart/form-data to request.POST. For other content types you have to use request.body property. for assertion of content type you can get the content type from request.META.get('CONTENT_TYPE')
def sample_view(request):
if request.META.get('CONTENT-TYPE') == 'application/json':
data = json.loads(request.body)
return JsonResponse({'any-message':'Hello'})

Categories