Я передал контекст is_liked to из PostListView в домашний шаблон, но почему оператор if post.is_liked
не работает? У меня есть функция like_post
, которая, когда пользователю понравился пост, is_liked will equal to true
и текст меняются с "не понравилось" на "понравилось". Но почему операторы if не работали (только показывали не понравившиеся) в шаблоне без сообщений об ошибках? Или я попытался изменить операторы if на {% post.user.is_liked %}
и {% user.is_liked %}
. Но все равно не сработало, в чем проблема? Благодарность
Models.py
class Post(models.Model):
title = models.CharField(max_length=100)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
likes = models.ManyToManyField(User, related_name='likes', blank=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
Views.py
def home(request):
context = {
'posts': Post.objects.all(),
}
return render(request, 'blog/home.html', context)
def like_post(request): # post like
post = get_object_or_404(Post, id=request.POST.get('post_id'))
is_liked = False
if post.likes.filter(id=request.user.id).exists():
post.likes.remove(request.user)
is_liked = False
else:
post.likes.add(request.user)
is_liked = True
return HttpResponseRedirect(post.get_absolute_url())
class PostListView(ListView):
model = Post
template_name = 'blog/home.html' # <app>/<model>_<viewtype>.html
context_object_name = 'posts'
ordering = ['-date_posted']
paginate_by = 10
is_liked = False
def get_context_data(self, *, object_list=None, **kwargs):
context = super(PostListView, self).get_context_data()
posts = context['posts']
for post in posts:
if post.likes.filter(id=self.request.user.id).exists():
context['is_liked'] = True
return context
class PostDetailView(DetailView):
model = Post
is_liked = False
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
post = context['post']
if post.likes.filter(id=self.request.user.id).exists():
context['is_liked'] = True
return context
Home.html
{% for post in posts %}
<form action="{% url 'like_post' %}" method="post">
{% csrf_token %}
{% if post.is_liked %} #I want to get whether the post is_liked by user
<h5>liked</h5>
{% else %}
<h5>not liked</h5>
{% endif %}
</form>
{% endfor %}
1 ответ
Вы можете аннотировать набор запросов таким образом, чтобы объекты Post
, которые возникают из этого, имели дополнительный атрибут .is_liked
с Exists
подзапрос [Django-doc]:
from django.db.models import Exists, OuterRef
class PostListView(ListView):
model = Post
template_name = 'blog/home.html'
context_object_name = 'posts'
ordering = ['-date_posted']
paginate_by = 10
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).annotate(
is_liked=Exists(Post.likes.through.objects.filter(
user_id=self.request.user.id,
post_id=OuterRef('pk')
))
)
Похожие вопросы
Новые вопросы
python
Python — это мультипарадигмальный многоцелевой язык программирования с динамической типизацией. Он предназначен для быстрого изучения, понимания и использования, а также обеспечивает чистый и унифицированный синтаксис. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Если у вас есть вопросы о версии Python, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas, NumPy) укажите это в тегах.