hello I have a post model which has a like(m2m) and user(forgeinkey) model field and Im trying to check if the request.user has liked the post and if they have, I should show them a red heart button else a blue heart should be shown, now since there are multiple posts and likes, Im looping through each like object to check if the request.user has liked it or not. Unfortunately for some reason, I couldn't implement a good logic and I see like button for every user. Some help would be appreciated.
Here's my model:
class post(models.Model):
user = models.ForeignKey(User,default='' , related_name='has_liked', on_delete=models.CASCADE)
caption = models.CharField(max_length=100)
image = models.FileField(upload_to='images/', null=True, blank=True)
video = models.FileField(upload_to='videos/', null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
like = models.ManyToManyField(User, null=True, blank=True, default='')
The View:
#login_required
def usersfeed(request):
users = User.objects.all()
posts = post.objects.filter(Q(user__in=request.user.profile.friend.all()) | Q(user=request.user)).order_by('-created')
comments = Comment.objects.all()
status_form = StatusForm(request.POST)
friend_requests = FriendRequest.objects.filter(to_user=request.user)
friends = request.user.profile.friend.all()
for i in posts:
likes = i.like.all()
print(likes)
for like in likes:
if like.username == request.user.username:
if request.user:
Hasliked = True
print('liked')
else:
Hasnotliked = True
print('not liked')
context = {
'Post':posts,
'User':users,
'form':PostForm(),
'Profile':profile,
'Form':CommentForm(),
'Comment':comments,
'Status':status_form,
'fr':friend_requests,
'friend':friends,
'Hasliked':Hasliked,
'Hasnotliked':Hasnotliked,
}
return render(request, 'social_media/feed.html', context=context)
The view for ajax like counter:
#login_required
def like_post(request):
Post = get_object_or_404(post, id=request.GET.get('post_id'))
cssClass = 'colorRed'
if Post.like.filter(id=request.user.id).exists():
Post.like.remove(request.user)
else:
Post.like.add(request.user)
count = Post.like.count()
users = Post.like.all()
user = []
for i in users:
user.append((i.username))
response = {
'count':count,
'users':user,
'cssClass':cssClass,
}
return JsonResponse(response)
The Html code:
{% for i in Post %}
<form action="{% url 'like_post' %}" class='like-submit' data-catid="{{ i.id }}" method="GET">
<div class="like">
{% if Hasliked == True %}
<button id="likeBtn{{ i.id }}" class="likeClassBtn colorRed">
<i class="fas fa-heart"></i>
</button>
{% endif %}
{% if Hasnotliked == True %}
<button id="likeBtn{{ i.id }}" class="likeClassBtn">
<i class="fas fa-heart"></i>
</button>
{% endif %}
<div class="show_likes">
<span id="likes_count{{ i.id }}">{{ i.total_likes }}</span>
<div class="username_liked">
<div id="user-likes{{ i.id }}" class="user-likes">
{% for p in i.like.all %}
{{ p.username }}
{% endfor %}
</div>
</div>
</div>
</div>
</form>
{% endfor %}
<script>
$(document).ready(function () {
$(".like-submit").submit(function (event) {
event.preventDefault()
const url = $(this).attr('action');
const catid = $(this).attr("data-catid");
$.ajax({
type: "GET",
url: url,
data: {
post_id: catid,
},
success: function (data) {
$('#likes_count' + catid).html(data.count)
if ($('#user-likes' + catid).html()){
$('#user-likes' + catid).html(data.users + ' ')
$('#likeBtn' + catid).toggleClass(data.cssClass)
}
}
});
});
});
</script>
you need to store the hasLiked/hasNotLiked in the post record for that user. The code above, implies that all posts are either liked or unliked. You also need to rethink the way you load your context- the current code is extremely inefficient. I would suggest to replace the Hasliked and Hasnotliked context entries with id arrays where each one will contains the ids of the posts that the current user liked/disliked. Then in the template do in check:
{% if i.id in Hasliked %}
<button id="likeBtn{{ i.id }}" class="likeClassBtn colorRed">
<i class="fas fa-heart"></i>
</button>
{% endif %}
{% if i.id in Hasnotliked %}
<button id="likeBtn{{ i.id }}" class="likeClassBtn">
<i class="fas fa-heart"></i>
</button>
{% endif %}
the hasliked, disliked can be loaded using your current setup:
friends = request.user.profile.friend.all()
for i in posts:
likes = i.like.all()
print(likes)
for like in likes:
if like.username == request.user.username:
if request.user:
Hasliked.append(i.id)
print('liked')
else:
Hasnotliked.append(i.id)
print('not liked')
This it would be extremely inefficient, the best way to si ur is to query the database directly, and simply returning the ids:
l_likedPosts = PostActions.objects.filter(user_id=l_currUser,
liked=True)
.values_list('post_id',flat=True)
Hasliked = list(l_likedPosts)
The code above assumes that you have a table PostActions that contains at least the user_id, the post_id and the liked/disliked status. This is generally what the manytomany field does for you, behind the scenes, but using it takes too much freedom in more complicated data models.
Related
I would like to add information in a form, coming from the model linked with a M2M relationship to the model I'm updating.The form works properly, but I'm not able to add any information.
Here is what I get:
Here is the expected result:
My solution: finally, I updated __str__() mthod in UserGroup model to display what I expect (but, at this stage, I lost the dynamic part and my view does not work anymore :-/)
The main model is Event and it's linked to Groups thanks to this relationship; in the form, all groups are listed and displayed with checkboxes, but I'm only able to display the groups' name, no other information.
It looks like I miss some data / information: the group name is displayed only because I use {{grp}}} (see below) but it has no attribute / filed available, even if it is initialized with a query from the group model.
I envisaged a workaround (see below) because my first tries made me consider this kind of solution, but I'm not able to reproduce what I did :-/
Any idea of what I did wrong, or any advice to manage this? Thanks in advance.
Here are related code parts.
Models:
class UserGroup(models.Model):
company = models.ForeignKey(
Company, on_delete=models.CASCADE, verbose_name="société"
)
users = models.ManyToManyField(UserComp, verbose_name="utilisateurs", blank=True)
group_name = models.CharField("nom", max_length=100)
weight = models.IntegerField("poids", default=0)
hidden = models.BooleanField(default=False)
def __str__(self):
return self.group_name
class Event(models.Model):
company = models.ForeignKey(
Company, on_delete=models.CASCADE, verbose_name="société"
)
groups = models.ManyToManyField(UserGroup, verbose_name="groupes", blank=True)
rules = [("MAJ", "Majorité"), ("PROP", "Proportionnelle")]
event_name = models.CharField("nom", max_length=200)
event_date = models.DateField("date de l'événement")
slug = models.SlugField()
current = models.BooleanField("en cours", default=False)
quorum = models.IntegerField(default=33)
rule = models.CharField(
"mode de scrutin", max_length=5, choices=rules, default="MAJ"
)
class Meta:
verbose_name = "Evénement"
constraints = [
models.UniqueConstraint(fields=["company_id", "slug"], name="unique_event_slug")
]
def __str__(self):
return self.event_name
Form:
class EventDetail(forms.ModelForm):
groups = forms.ModelMultipleChoiceField(
label = "Liste des groupes",
queryset = None,
widget = forms.CheckboxSelectMultiple,
required = False
)
class Meta:
model = Event
fields = ['event_name', 'event_date', 'quorum', 'rule', 'groups']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
instance = kwargs.get('instance', None)
self.fields['groups'].queryset= UserGroup.objects.\
filter(company=instance.company).\
order_by('group_name')
View:
#user_passes_test(lambda u: u.is_superuser or (u.id is not None and u.usercomp.is_admin))
def adm_event_detail(request, comp_slug, evt_id=0):
'''
Manage events creation and options
'''
company = Company.get_company(request.session['comp_slug'])
# all_groups = list(UserGroup.objects.filter(company=company, hidden=False).order_by('group_name').values())
if evt_id > 0:
current_event = Event.objects.get(id=evt_id)
event_form = EventDetail(request.POST or None, instance=current_event)
else:
event_form = EventDetail(request.POST or None)
event_form.fields['groups'].queryset = UserGroup.objects.\
filter(company=company, hidden=False).\
order_by('group_name')
if request.method == 'POST':
if event_form.is_valid():
if evt_id == 0:
# Create new event
event_data = {
"company": company,
"groups": event_form.cleaned_data["groups"],
"event_name": event_form.cleaned_data["event_name"],
"event_date": event_form.cleaned_data["event_date"],
"quorum": event_form.cleaned_data["quorum"],
"rule":event_form.cleaned_data["rule"]
}
new_event = Event.create_event(event_data)
else:
new_event = event_form.save()
else:
print("****** FORMULAIRE NON VALIDE *******")
print(event_form.errors)
return render(request, "polls/adm_event_detail.html", locals())
HTML (I did not put each parts of the 'accordion' widget, I do not think they have anything to do with the problem):
{% if evt_id %}
<form action="{% url 'polls:adm_event_detail' company.comp_slug evt_id %}" method="post">
{% else %}
<form action="{% url 'polls:adm_create_event' company.comp_slug %}" method="post">
{% endif %}
{% csrf_token %}
<!-- Hidden field where the referer is identified to go back to the related page after validation -->
<input type="hidden" name="url_dest" value="{{ url_dest }}" />
<br>
<!-- Accordion -->
<div id="eventDetails" class="accordion shadow">
<div class="card">
<div class="card-header bg-white shadow-sm border-0">
<h6 class="mb-0 font-weight-bold">
Evénement
</h6>
</div>
<div class="card-body p-5">
<p>Nom : {{event_form.event_name}} </p>
<p>Date : {{event_form.event_date}} </p>
</div>
</div>
<!-- Accordion item 2 - Event's groups -->
<div class="card">
<div id="headingTwo" class="card-header bg-white shadow-sm border-0">
<h6 class="mb-0 font-weight-bold">
<a href="#" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo" class="d-block position-relative collapsed text-dark collapsible-link py-2">
Groupes d'utilisateurs
</a>
</h6>
</div>
<div id="collapseTwo" aria-labelledby="headingTwo" data-parent="#eventDetails" class="collapse show">
<div class="card-body p-5">
<p>Sélectionnez le(s) groupe(s) d'utilisateurs participants à l'événement :</p>
<ul>
{% for grp in event_form.groups %}
<li>{{ grp }}
{{ grp.weight }}
{{ grp.hidden }}
{{ grp.nb_users }}
</li>
{% endfor %}
</ul>
<p></p>
</div>
</div>
</div>
</div> <!-- Accordion end -->
<button class="btn btn-success mt-5" type="submit">{% if evt_id %}Mettre à jour{% else %}Créer{% endif %}</button>
     
<a class="btn btn-secondary back_btn mt-5" href="*">Annuler</a>
<div class="row">
<div hidden>
<!-- List of groups in event -->
{{ event_form.group_list }}
</div>
</div>
</form>
Workaround
If it's not possible to achieve this directly, I thought to a workaround that would be implemented in several parts:
Create a list almost like the queryset: group_list = UserGroup.objects.filter(company=instance.company).order_by('group_name').values()
I already know I can display each group with its details and a checkbox
on client side (javascript), I manage an hidden list that would be part of the form, with the ID of each selected group. That means that the list will be dynamically updated when a box is checked on unchecked
on the POST request, read the list to update the group attribute of updated event.
I would have prefered the users actions having effect directly to the form, but I know this could work
You're accessing the form's groups field, not the model instance. The form field doesn't have any relationship to other models, it's just a field. You can access the underlying instance of the model form using form.instance.
Also note that you get a relationship manager object when querying related models. Hence, use .all to query all groups.
Try
<ul>
{% for grp in event_form.instance.groups.all %}
<li>{{ grp }}
{{ grp.weight }}
{{ grp.hidden }}
{{ grp.nb_users }}
</li>
{% endfor %}
</ul>
I'm trying to filter a model called "CartItem" , that has a field called item , I want to check whether a product id is in this field. each cartitem instance is connected to a cart.id. The product id is taken from a form in templates.
I currently have " {% if cartitem.objects.filter(item_id=product_id).exists %} " in the template, I also tried making an items list in the views.py , to try to use the "if in" statement in the template, based off the "items" contents, the only problem was that when the browser is refreshed the for loop to create this list is not called , it is only called when the user clicks on the "add to cart" button. Hope that makes sense.
at the moment I get an error:
TemplateSyntaxError
Exception Value:
Could not parse the remainder: '(item.id=product.id).exists' from 'cartitem.objects.filter(item.id=product.id).exists'
Thanks
models.py
class CartItem(models.Model):
item = models.ForeignKey(Product, blank=True, on_delete=models.CASCADE, null=True)
items_cart = models.ForeignKey('Cart', blank=True, on_delete=models.CASCADE, null=True)
quantity = models.IntegerField(null=True, blank=True)
updated = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return 'item:{} cart:{} quantity:{}'.format(self.item, self.items_cart, self.quantity)
views.py
def cart_update(request):
product_id = request.POST.get('product_id')
cart_obj, new_obj = Cart.objects.new_or_get(request)
cart_items = CartItem.objects.filter(items_cart_id=cart_obj)
items = []
for item in cart_items:
items.append(item.item.id)
print(items)
if product_id is not None:
try:
product_obj = Product.objects.get(id=product_id)
except Product.DoesNotExist:
print("Show message to user, product is gone?")
return redirect("cart:home")
cart_obj, new_obj = Cart.objects.new_or_get(request)
cart_items = CartItem.objects.filter(items_cart_id=cart_obj)
if product_obj in cart_items:
cart_items.delete(product_obj)
added = False
else:
newitem = CartItem(item=product_obj, items_cart=cart_obj, quantity=1)
newitem.save()
added = True
request.session['cart_items'] = cart_items.count()
# return redirect(product_obj.get_absolute_url())
if request.is_ajax(): # Asynchronous JavaScript And XML / JSON
print("Ajax request")
json_data = {
"added": added,
"removed": not added,
"cartItemCount": cart_items.count()
}
return JsonResponse(json_data, status=200) # HttpResponse
# return JsonResponse({"message": "Error 400"}, status=400) # Django Rest Framework
return redirect("cart:home")
cart.html
<form class='form-product-ajax' method='POST' action='{% url "cart:update" %}' data-endpoint='{% url "cart:update" %}' class="form" {% if request.user.is_authenticated %}data-user='abc'{% endif %}> {% csrf_token %}
<input type='hidden' name='product_id' value='{{ product.id }}' {% if product.is_digital %}data-is-digital='true'{% endif %}/>
<span class='submit-span'>
{% if cartitem.objects.filter(item_id=product_id).exists %}
<div class='btn-group'> <a class='btn btn-link' href='/cart/'>In cart</a> <button type='submit' class='btn btn-link'>Remove?</button></div>
{% else %}
<button type='submit' class='btn btn-success'>Add to cart</button>
{% endif %}
</span>
</form>
you can not use this syntax in template django:
cartitem.objects.filter(item.id=product.id).exists
you can use templatetags and call it in your template:
register = template.Library()
#register.filter
def existing_product(product):
return CartItem.objects.filter(item.id=product.id).exists()
then load your templatetag in your template
{% load file_name_containing_your_method %}
<form class='form-product-ajax' method='POST' action='{% url "cart:update" %}' data-endpoint='{% url "cart:update" %}' class="form" {% if request.user.is_authenticated %}data-user='abc'{% endif %}> {% csrf_token %}
<input type='hidden' name='product_id' value='{{ product.id }}' {% if product.is_digital %}data-is-digital='true'{% endif %}/>
<span class='submit-span'>
{% if product|existing_product %}
<div class='btn-group'> <a class='btn btn-link' href='/cart/'>In cart</a> <button type='submit' class='btn btn-link'>Remove?</button></div>
{% else %}
<button type='submit' class='btn btn-success'>Add to cart</button>
{% endif %}
</span>
</form>
hope this can help your second question
NB: you should reboot your server after adding a templatetag
I have a form that I am trying to implement with Ajax, after inputing some content on the textbox, when I click on the sumbit button using my mouse, everything works fine (page didnt refresh, data posted on database, and new data displayed on the page). But when I try to submit data by pressing enter, the page is displaying only the serialized data from my form (nothing more, html file do not work)and it says in the console:
Resource interpreted as Document but transferred with MIME type application/json: "http://localhost:8000/try/".
current page looks exactly like this after pressing enter button(nothing more):
{"task": {"id": 52, "todo": "wws", "author": 1, "completed": false}}
these are the data that came from my form.
this is my views.py
class TodoList(View):
def get(self, request):
todo_list = ToDo.objects.filter(author_id=request.user.id)
form = AddTodo()
context = {
'todo_list': todo_list,
'form': form,
}
return render(request, 'trylangto/try.html', context)
def post(self, request):
form = AddTodo(request.POST)
if form.is_valid():
form.instance.author_id = request.user.id
new_form = form.save()
return JsonResponse({'task': model_to_dict(new_form)}, status=200)
else:
return redirect('trylang:todo-list')
return redirect('trylang:todo-list')
this is my main.js:
$(document).ready(function(){
$("#createbutton").click(function(){
var formdata = $("#addtodoform").serialize();
$.ajax({
url: $("#addtodoform").data('url'),
data: formdata,
type: 'post',
success: function(response){
$("#tasklist").append('<div class="card mb-1" ><div class="card-body">'+ response.task.todo +'<button type="button" class="close"><span aria-hidden="true">×</span></button></div></div>')
}
});
});
});
and here is my template:
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
{% if user.is_authenticated %}
<div class="media content-section">
<form class="media-body pt-3" method="POST" id="addtodoform" data-url="{% url 'trylang:todo-list' %}">
{% csrf_token %}
<legend><h5>add new tasks</h5></legend>
<fieldset class="form-group ">
{{ form|crispy}}
</fieldset>
<button class="btn btn-outline-info float-right" type="button" id="createbutton">add</button>
</form>
</div>
{% endif %}
<div id="tasklist">
{% for task in todo_list %}
<div class="card mb-1" >
<div class="card-body">
{{task.todo}}
<button type="button" class="close">
<span aria-hidden="true">×</span>
</button>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
UPDATE: I am including my models.py just in case
class ToDo(models.Model):
todo = models.CharField(max_length=500)
date_posted = models.DateTimeField(default=timezone.now, editable=False)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='users')
completed = models.BooleanField(default=False)
this is what I get on the console when I use console.log(formdata):
csrfmiddlewaretoken=N91OUGSd6kBFkB1E2DMZuMW6qJD7cc3frPprwGMLTuupcg6PKYtt44jA4z5Lx6xX&todo=this%20is%20the%20content%20of%20my%20textbox
You don't need model_to_dict. So, try:
if form.is_valid():
form.instance.author_id = request.user.id
new_form = form.save()
return JsonResponse({'task': new_form}, status=200)
else:
return redirect('trylang:todo-list')
return redirect('trylang:todo-list')
EDIT
You are submitting the form not through ajax. When you click button it was submitting the form. So, e.preventDefault() should do the job.
$(document).ready(function(){
$("#createbutton").click(function(e){
e.preventDefault(); <--- You were missing this
var formdata = $("#addtodoform").serialize();
$.ajax({
url: $("#addtodoform").data('url'),
data: formdata,
type: 'post',
success: function(response){
$("#tasklist").append('<div class="card mb-1" ><div class="card-body">'+ response.task.todo +'<button type="button" class="close"><span aria-hidden="true">×</span></button></div></div>')
}
});
});
});
I have endless pagination working on my site for posts.
Each post has a like and dislike button which works using ajax.
The first set of posts have working buttons but all posts delivered with pagination don't have working buttons. When clicking the buttons they don't even run the ajax to send a query to my views.py file but the first set of posts have working ones.
urls.py
path("likepost/", user_views.like_post_view, name='like_post'),
path("dislikepost/", user_views.dislike_post_view, name='dislike_post'),
views.py file
sort = request.GET.get("sort")
if sort=="newest":
posts = Post.objects.filter(deleted=False).order_by('-date_posted')
sort_type = "newest"
if sort=="oldest":
posts = Post.objects.filter(deleted=False).order_by('date_posted')
sort_type = "oldest"
if sort=="top-alltime":
posts = Post.objects.filter(deleted=False).annotate(like_count=(Count('like_post')-Count("dislike_post"))).order_by('-like_count')
sort_type = "top-alltime"
if sort==None or sort=="top-today":
today = datetime.now().date()
today_start = datetime.combine(today, time())
posts = Post.objects.filter(deleted=False, date_posted__gte=today_start).annotate(like_count=(Count('like_post')-Count("dislike_post"))).order_by('-like_count')
sort_type = "top-today"
if sort=="top-week":
current_week = date.today().isocalendar()[1]
posts = Post.objects.filter(deleted=False, date_posted__week=current_week).annotate(like_count=(Count('like_post')-Count("dislike_post"))).order_by('-like_count')
sort_type = "top-week"
page = request.GET.get('page', 1)
paginator = Paginator(posts, 4)
trending_tags = Post.tags.most_common()[:5]
try:
posts_given = paginator.page(page)
except PageNotAnInteger:
posts_given = paginator.page(1)
except EmptyPage:
posts_given = paginator.page(paginator.num_pages)
context = {
"trending_tags": trending_tags,
"posts_given": posts_given,
"sort": sort_type
}
return render(request, "users/index.html", context)
#login_required
#require_GET
def like_post_view(request):
print("LIKE REQUESTED!!!!!!!!!!!!!")
if request.method == 'GET':
user = request.user
user = User.objects.get(username=user)
post_id = request.GET.get('post_id', None)
post = Post.objects.get(id=post_id)
if like_post.objects.filter(user=user, post=post).exists():
# user has already liked this post
# remove like/user
like_post.objects.filter(user=user, post=post).delete()
#return -1
return HttpResponse(-1)
else:
# add a new like for the post
like_post.objects.create(post=post, user=user)
if dislike_post.objects.filter(user=user, post=post).exists():
dislike_post.objects.filter(user=user, post=post).delete()
return HttpResponse(+2)
return HttpResponse(+1)
#login_required
#require_GET
def dislike_post_view(request):
print("DISLIKE REQUESTED!!!!!!!!!!!!!")
if request.method == 'GET':
user = request.user
user = User.objects.get(username=user)
post_id = request.GET.get('post_id', None)
post = Post.objects.get(id=post_id)
if dislike_post.objects.filter(user=user, post=post).exists():
# user has already disliked this post
# remove dislike/user
dislike_post.objects.filter(user=user, post=post).delete()
return HttpResponse(+1)
else:
# add a new dislike for the post
dislike_post.objects.create(post=post, user=user)
if like_post.objects.filter(user=user, post=post).exists():
like_post.objects.filter(user=user, post=post).delete()
return HttpResponse(-2)
return HttpResponse(-1)
template
{% load static %}
{% block content %}
<h1>Homepage</h1>
<div class="infinite-container" id="infinite-container" style="max-width:700px;width:100%;margin-left:auto;margin-right:auto;">
<form action="/action_page.php">
{% csrf_token %}
<div style="display:inline-block;">
<h5 style="margin-left:10px;">Sort by</h5>
<select name="sort" class="sort_by" id="sort_by" style="margin-left:10px;">
<option value="newest">Newest</option>
<option value="top-today" selected="selected">Top Today</option>
<option value="top-week">Top This Week</option>
<option value="top-alltime">Top All Time</option>
<option value="oldest">Oldest</option>
</select>
</div>
</form>
{% for post in posts_given %}
<div class="post infinite-item" style="background-color:#494a4d;border-radius: 8px; color: white;padding:10px;margin:10px;">
<h2>{{ post.title }}<h2>
<hr>
<img src="/uploads/{{ post.image }}" alt="{{ post.image }}" style="max-width:100%; max-height:500px;">
<hr>
<div class="row-post">
<div class="column-post-left">
<h4 style="text-align: left;">by {{ post.user.username }} | {{ post.date_posted | timesince }} ago {% if request.user.is_authenticated and post.user == request.user %} | edit{% else %} | report{% endif %}</h4>
<h5 style="word-wrap: break-word;word-break: break-word;">{% for tag in post.tags.all %} #{{ tag }}{% endfor %}</h5>
<h5>{{ post.comment_count }} comments</h5>
</div>
<div class="column-post-right">
<input src="{% static "memeplaza/rocket_white.png" %}" type="image" style="max-width:50px;max-height:50px;" class="like" name="{{ post.id }}" value="Like"/>
<p style="font-size:22px;" id="{{ post.id }}">{{ post.like_count }}</p>
<input src="{% static "memeplaza/flash_white.png" %}" style="max-width:50px;max-height:50px;" type="image" class="dislike" name="{{ post.id }}" value="Dislike" />
</div>
</div>
</div>
{% endfor %}
</div>
{% if posts_given.has_next %}
<a class="infinite-more-link" href="?sort={{ sort }}&page={{ posts_given.next_page_number }}"></a>
{% endif %}
<script>
var infinite = new Waypoint.Infinite({element: $('.infinite-container')[0]});
$('.sort_by').change(function(){
var sort_type = $('#sort_by :selected').val();
window.location = "/?sort="+sort_type;
})
$('.like').click(function(){
var id = $(this).attr('name');
console.log("Like button pressed!");
$.ajax({
type: "GET",
url: "{% url 'like_post' %}",
data: {'post_id': $(this).attr('name'), 'csrfmiddlewaretoken': '{{ csrf_token }}'},
dataType: "json",
success: function(response){
var score = $("#" + id).text();
score = score.split(" ")[0];
score = parseInt(score) + parseInt(response);
$("#" + id).text(score);
}
});
})
$('.dislike').click(function(){
var id = $(this).attr('name');
console.log("disLike button pressed!");
$.ajax({
type: "GET",
url: "{% url 'dislike_post' %}",
data: {'post_id': $(this).attr('name'), 'csrfmiddlewaretoken': '{{ csrf_token }}'},
dataType: "json",
success: function(response){
var score = $("#" + id).text();
score = score.split(" ")[0];
score = parseInt(score) + parseInt(response);
$("#" + id).text(score);
}
});
})
</script>
{% if sort is not empty %}
<script>
$(document).ready(function(){
$("#sort_by").val("{{ sort }}");
});
</script>
{% endif %}
{% endblock content %}```
You should use $('selector').on for binding events to elements that do not exist yet
$('#infinite-container').on('click', '.like', function() {
...
})
$('#infinite-container').on('click', '.dislike', function() {
...
})
Using $('.like').click will only bind the event handler to elements that currently exist on the page
I create a financial manager and I need the user to change the account activity (indicate an active account or not), but when I send the form for change, then the model attribute does not change and always remains TRUE
I also tried to do this through a copy of the Account, but it was also not a result of the outcome
Account.objects.get(user=self.request.user, id=id).is_active = False
models.py
class Account(models.Model):
type_of_currency = models.CharField(max_length=20)
user = models.ForeignKey(get_user_model(), blank=True,
related_name='user_account',
on_delete=models.CASCADE)
count = models.DecimalField(max_digits=12, decimal_places=2, blank=True)
created = models.DateTimeField(default=datetime.datetime.now)
is_active = models.BooleanField()
def __str__(self):
return f'{self.type_of_currency} - {self.count}'
views.py
class AccountDetailView(DetailView, UpdateView):
model = Account
form_class = AccountCreateForm
template_name = 'account_detail.html'
def post(self, request, *args, **kwargs):
id = self.request.POST['accountid']
self.request.user.user_account.get(id=6).is_active = False
print(self.request.user.user_account.get(
id=id).is_active) # always True why?
return redirect('/counts/' + id)
template
{% extends 'base.html' %}
{% block content %}
<div class="col-sm-5">
<h1>account: {{ account.id }}</h1>
<p><strong>Author:</strong> {{ account.user }}</p> <!-- author detail link not yet defined -->
<p><strong>Type:</strong> {{ account.type_of_currency }}</p>
<p><strong>count:</strong> {{ account.count }}</p>
<p><strong>IsCreated:</strong> {{ account.created }}</p>
<p><strong>IsActive:</strong>{{ account.is_active }}</p>
<a class="btn btn-outline-primary"
href="{% url 'account-list' %}">Back</a>
{% if account.is_active %}
<form method="post">
{% csrf_token %}
<input type="hidden" value="{{ account.id }}" name="accountid">
<button type="submit" class="btn btn-outline-danger">Deactivate</button>
</form>
{% else %}
<form method="post">
{% csrf_token %}
<button type="submit" class="btn btn-outline-success">Activate</button>
</form>
{% endif %}
</div>
{% endblock %}
In the post method DetailViews, I expect that after the button is pressed, user activity will change, but the result is always True
You're never commiting change to DB.
Also, I wouldn't use the following syntax: self.request.user.user_account.get(id=6).is_active = False
You can try: self.request.user.user_acocount.filter(id=6).update(is_active=False)
But, if you're dead set on using .get():
user_acc = self.request.user.user_account.get(id=6)
user_acc.is_active = False
user_acc.save()