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

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.

Related

How to update a value in database after n seconds of query made? Django

I have a model in which I created a field "bargain price " as shown in Models.py:
class Item(models.Model):
title = models.CharField(max_length=100)
price = models.FloatField()
bargainprice = models.FloatField(default=0)
somewhere in my template I take input from user and update the bargain price using ajax as shown below:
$.ajax({
url: "/bargain/" + id + "/",
data: { csrfmiddlewaretoken: window.CSRF_TOKEN, 'input': parseFloat(input) },
type: 'POST'
}).done(function (response) {
alert(response);
});
and I successfully update the price by the view:
def Bargain(request, uid):
if request.method == 'POST':
item = Item.objects.get(id=uid)
item.bargainprice = request.POST['input']
item.save()
message = 'update successful'
return HttpResponse(message)
else:
return HttpResponse("this is not working..")
**Now what I want. I want to reset this Bargain_price updated value to default after n seconds **
Can anyone suggest to me the method to do it? Thanks in advance.

Using Ajax to receive total amount due before submitting to database

Trying to use Ajax to calculate and display the sum before I submit anything to the database. At the moment this is what I have, but I can't seem to get anything to display. I'm trying to start small and see if I'm even able to display the values in the fields.. Is my view for final_price wrong? Or did I mess up somewhere in the Jquery? I'm still new to Ajax, so I'm not sure where I went wrong (following tutorials)
Book Price: $10 (input field)
Delivery charge: $3 (input field)
Delivery type: $5 (input field)
[calculate] [submit]
Final Result: $18 (result of adding the fields above when user clicks the calculate button)
calculate button will display $18
submit button will finalize the results and send the values to the database.
This is my model for the table
class book(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
book_price = models.IntegerField()
delivery_charge = models.IntegerField()
delivery_type = models.IntegerField()
final_result = models.IntegerField()
def save(self, *args, **kwargs):
self.final_result = self.book_price + self.delivery_charge + self.delivery_type
print(self.final_result)
super(book, self).save(*args, **kwargs)
views.py for the form
def final_price(request):
response_data = {}
if request.method == 'POST':
form = RequestForm(request.POST)
book_price = request.POST.get('book_price')
delivery_charge = request.POST.get('delivery_charge')
delivery_type = request.POST.get('delivery_type')
response_data['book_price'] = book_price
response_data['delivery_charge'] = delivery_charge
response_data['delivery_type'] = delivery_type
book.objects.create(book_price=book_price, delivery_charge=delivery_charge,delivery_type=delivery_type)
return JsonResponse(response_data)
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.save()
return redirect('final_price')
else:
form = RequestForm()
args = {'form': form}
return render(request, 'final_price.html', args)
Model for to allow me to edit the fields in my book module
class RequestForm(forms.ModelForm):
class Meta:
model = book
fields = (
'book_price',
'delivery_charge',
'delivery_type',
)
Html file
{% extends 'base.html' %}
{% block content %}
<form class="post" method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" name="button">Submit</button>
</form>
<br>
<button onclick="myFunction()">Get Quote</button>
<script type="text/javascript">
function myFunction(){
$('.ajaxProgress').show();
$.ajax({
type: "POST",
url: "/final_price",
dataType: "json",
async: true,
data:{
csrfmiddlewaretoken: '{{ csrf_token }}',
book_p: $('#book_price').val(),
},
success: function(json){
$('#output').html(json.message);
$(.ajaxProgress).hide();
}
});
}
</script>
{% endblock %}
urls.py
urlpatterns = [
path('', views.home, name='home'),
path('final_price/', views.final_price, name='final_price'),
]

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 Ajax 405 (Method Not Allowed) CBV

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

How to display the name that matches the ID without refreshing/submitting the form in Django?

I am trying to display a User's name on top of a box where they enter their Employee # in a form, without having to refresh the page.
For example, they enter their # and then after they click/tab onto the next field, it renders their name on top, which comes from the database, so the user knows they've entered the correct info. This name is stored in a separate model, so I try to retrieve it using the "id/number".
I am not too familiar with AJAX but after reading a few similar questions it seems like an AJAX request would be the most appropriate way to achieve this. I tried to make a function get_employee_name that returns the name of the person based on the way I saw another ajax request worked, but I'm not sure how to implement this so it displays after the # is entered.
My page currently loads, but there is never a call to the function/url that searches for the name to display it on the page (because there isn't one). I'm not sure where I might be missing the part that connects these two areas of the code or how to connect these, as I am not too familiar with html and Django, most of this has been trial and error.
models.py
class EmployeeWorkAreaLog(TimeStampedModel, SoftDeleteModel, models.Model):
employee_number = models.ForeignKey(Salesman, on_delete=models.SET_NULL, help_text="Employee #", null=True, blank=False)
work_area = models.ForeignKey(WorkArea, on_delete=models.SET_NULL, null=True, blank=False)
station_number = models.ForeignKey(StationNumber, on_delete=models.SET_NULL, null=True, blank=True)
This is the model where the name is stored
alldata/models.py
class Salesman(models.Model):
slsmn_name = models.CharField(max_length=25)
id = models.IntegerField(db_column='number', primary_key=True)
I was reading I can add to the "attrs" in the widget an 'onchange' part, but I am not too familiar with how to approach this and tying it to the ajax request from forms and not the html.
forms.py
class WarehouseForm(AppsModelForm):
class Meta:
model = EmployeeWorkAreaLog
widgets = {
'employee_number': ForeignKeyRawIdWidget(EmployeeWorkAreaLog._meta.get_field('employee_number').remote_field, site, attrs={'id':'employee_number_field'}),
}
fields = ('employee_number', 'work_area', 'station_number')
views.py
def enter_exit_area(request):
form = WarehouseForm(request.POST or None)
if form.is_valid():
# Submission stuff/rules
return render(request, "operations/enter_exit_area.html", {
'form': form,
})
def get_employee_name(request):
employee_number = request.GET.get('employee_number')
try:
employee = Salesman.objects.get(id=employee_number)
except Salesman.DoesNotExist:
return JsonResponse({'error': 'Employee not found'}, status=404)
employee_name = employee.slsmn_name
return JsonResponse({'employee_name': employee_name})
urls.py
urlpatterns = [
url(r'enter-exit-area/$', EnterExitArea.as_view(), name='enter_exit_area'),
path('get-employee-name/', views.get_employee_name, name='get_employee_name'),
]
The ajax request I tried to create is at the end of this html. I modified a similar request I found, but it does not actually display anything on the screen, not sure if I'm missing an area where the request is actually never being called, as I am not too familiar with how these types of requests work.
enter_exit_area.html
{% extends "base.html" %}
{% block main %}
<form id="warehouseForm" action="" method="POST" novalidate >
{% csrf_token %}
<div>
<div>
<!-- Here is where I would want the name to render after the user enters their number and tabs out -->
{{ form.employee_number.help_text }}
{{ form.employee_number }}
</div>
<div>
{{ form.work_area.help_text }}
{{ form.work_area }}
</div>
</div>
<div>
<div>
<button type="submit" name="enter_area" value="Enter">Enter Area</button>
</div>
</div>
</form>
<script>
$("#id_employee_number").change(function () {
var employee_number = $(this).val();
var url = $("#warehouseForm").data("employee-name");
$.ajax({
url: url,
type:'GET',
data: {
'id': employee_number
},
success: function (data) {
var employee_name = data['employee_name'];
$('#employee_name').text(employee_name);
},
error : function (data) {
var error_message = data['error'];
$('#employee_name').text(error_message);
}
});
});
</script>
{% endblock main %}
How can I call the function from the HTML? Could I do it in such a way that when the user enters 6 numbers it checks? (All employee numbers are 6 digits)
The url has to be the endpoint url which you defined in your url.py file
<script>
$("#id_employee_number").change(function (e) {
e.preventDefault();
var employee_number = $(this).val();
var url = $("#warehouseForm").data("employee-name");
$.ajax({
url: "/get_employee_name", // Here
type:'GET',
data: {
'id': employee_number
},
success: function (data) {
var employee_name = data['employee_name'];
$('#employee_name').text(employee_name);
},
error : function (data) {
var error_message = data['error'];
$('#employee_name').text(error_message);
}
});
});
</script>
You can append to your GET request a url parameter like: /get-employee-name/<your employee number here>
I recommend taking a look at URL Dispatcher to create url parameters within your django url definitions
I also recommend using underscores NOT dashes in your url definitions.
So a pseudo working config would be
urls.py
urlpatterns = [
url(r'enter-exit-area/$', EnterExitArea.as_view(), name='enter_exit_area'),
path('get_employee_name/<int:employeeNum>', views.get_employee_name, name='get_employee_name'),
]
views.py
def get_employee_name(request, employeeNum): #You get the employeeNum variable from urls.py
try:
employee = Salesman.objects.get(id=employee_number)
except Salesman.DoesNotExist:
return JsonResponse({'error': 'Employee not found'}, status=404)
employee_name = employee.slsmn_name
return JsonResponse({'employee_name': employee_name})
script
<script>
$("#id_employee_number").change(function () {
var employee_number = $(this).val();
var employeeNum = $("#warehouseForm").data("employee-name");
$.ajax({
url: `/get_employee_name/${employeeNum}`,
type:'GET',
success: function (data) {
var employee_name = data['employee_name'];
$('#employee_name').text(employee_name);
},
error : function (data) {
var error_message = data['error'];
$('#employee_name').text(error_message);
}
});
});
</script>

Categories