#python #html #django #templates #model
#python #HTML #django #шаблоны #Модель
Вопрос:
я пытаюсь сделать кнопку «Мне нравится». И все работает нормально, за исключением того факта, что я не могу проверить (внутри шаблона), нравится ли что-то пользователю. Другими словами, я не могу проверить наличие существующей строки в базе данных.
Я пытаюсь сделать это для шаблона: если пользователю нравится сообщение. Этот пост показывает заполненное сердце, в противном случае он показывает только контур сердца
{% for post in posts %}
{% if post in likelist %}
<i class="fa fa-heart like" data-id="{{ post.id }}" id="like-{{ post.id }}" style="color:red;"></i>
{% else %}
<i class="fa fa-heart-o like" data-id="{{ post.id }}" id="like-{{ post.id }}" style="color:red;">
</i>
{% endif %}
{% endfor %}
Но оператор if всегда выдает False, даже если пользователю действительно нравится сообщение.
Вот модель:
class Likelist(models.Model):
user = models.ForeignKey('User', on_delete=models.CASCADE, related_name='liker')
likes = models.ForeignKey('Posts', on_delete=models.CASCADE, related_name='likes')
def __str__(self):
return f"{self.user} likes {self.likes}"
И я передаю контекст в views.py сквозной рендеринг
return render(request, "network/profile.html", {
#[...]some other contexts
"posts": Posts.objects.filter(user=user_id).order_by('-timestamp'),
"likelist": Likelist.objects.filter(user=request.user),
})
Если я попытаюсь напечатать его в теге HTML ( {{likelist}} или {{posts}} ), появятся наборы запросов, поэтому контекст передается нормально.
Я не знаю, почему условие не проверяет наличие элемента в базе данных
Комментарии:
1.
likelist
является наборомLikelist
объектов,post
являетсяPost
объектом, поэтомуPost
объект никогда не может быть внутриlikelist
.
Ответ №1:
likelist
это коллекция Likelist
объектов, post
это Post
объект, поэтому Post
объект никогда не может быть внутри likelist
.
Но даже если бы это было так, проверять членство таким образом не рекомендуется, поскольку это создаст дополнительный запрос для каждого Post
объекта. Вы можете аннотировать Post
s и проверять, понравились ли они, с помощью Exists
подзапроса [Django-doc]:
from django.db.models import Exists, OuterRef
posts = Posts.objects.filter(
user=user_id
).annotate(
is_liked=Exists(Likedlist.objects.filter(
likes=OuteRef('pk'), user=user_id
))
).order_by('-timestamp')
return render(request, 'network/profile.html', {
'posts': posts,
})
Затем в шаблоне вы проверяете с помощью:
{% for post in posts %}
{% if post.is_liked %}
…
{% else %}
…
{% endif %}
{% endfor %}
Примечание: обычно модели Django присваивается единственное имя, поэтому
Post
вместо.Posts