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
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.
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'),
]
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>
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
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>