Проверьте, есть ли элемент в модели — Шаблоны Django

#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 .