Невозможно получить доступ к значениям словаря с помощью jinja

Вот мой views.py

def following(request):
    currentUser = User.objects.get(pk=request.user.id)
    currentUser_followings = Following_System.objects.get(user=currentUser).following
    allPosts = Post.objects.all().order_by("-timestamp").reverse()
    followingPosts = []
    for user in currentUser_followings.all():
        for post in allPosts:
            if post.author == user:
                followingPosts.append(post)
    
    **post_likers_ids = {post.id: list(post.likers.values_list('id', flat=True)) for post in followingPosts}**

    # Show 10 posts per page.
    paginator = Paginator(followingPosts, 5) 
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    return render(request, "network/following.html",{
        "page_obj": page_obj,
        "post_likers_ids" : post_likers_ids
    })

Я отлаживаю, и post_likers_ids возвращаются: ({4: [2], 2: [1,3,5]}) И теперь в моем следующем html, почему условие if всегда ложно (Хотя оно должно быть истинным для некоторых, потому что я знаю ожидаемый входной вывод):

        {% for post in page_obj %}
        <div class="list-group-item">
            {% with post_id=post.id %}
                {% if user.id in post_likers_ids.post_id %}
                  <p>The user liked this </p>
                {% else %}
                  <p>The user have not liked this </p>
                {% endif %}
            {% endwith %}
        </div>
        {% endfor %}

Вот моя модель, если это поможет:

class Post(models.Model):
    content = models.TextField(blank=False)
    author = models.ForeignKey("User", on_delete=models.CASCADE, related_name="author")
    timestamp = models.DateTimeField(auto_now_add=True)
    likers = models.ManyToManyField("User", related_name="liked_posts", blank=True)

    def serialize(self):
        likes_count = self.likers.count()  #
        likers = [user.id for user in self.likers.all()]
        
        return {
            "id": self.id,
            "content": self.content,
            "author": self.author.username,
            "author_id": self.author.id,
            "timestamp": self.timestamp.strftime("%b %d %Y, %I:%M %p"),
            "likes": likes_count,
            "likers" : likers,
        }

Похоже, что при использовании шаблона jinja,

post_likers_ids.post_id

ведут себя странно, например, когда post_id = 4; используя

post_likers_ids.4

возвращает правильное значение, но использование post_likers_ids.post_id возвращает пустое значение

Вы можете проверить это с помощью:

{% if user.id in post_likers_ids[post_id] %}
    <!-- … -->
{% endif %}

Но само построение такого словаря неэффективно, так как это вызовет n запросов для n постов.

Мы можем повысить эффективность, работая с JOIN для определения авторов, за которыми мы следим, и, кроме того, позволяя базе данных определить, понравился ли пост, с помощью подзапроса Exists [Django-doc]:

from django.db.models import Exists, OuterRef


def following(request):
    followingPosts = (
        Post.objects.filter(author__following__user=request.user)
        .order_by('-timestamp')
        .annotate(
            is_liked=Exists(
                Post.likers.through.objects.filter(
                    user=request.user, post_id=OuterRef('pk')
                )
            )
        )
        .distinct()
    )

    # Show 10 posts per page.
    paginator = Paginator(followingPosts, 5)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    return render(
        request,
        'network/following.html',
        {
            'page_obj': page_obj,
        },
    )

Тогда в шаблоне мы получим:

{% for post in page_obj %}
    <!-- … -->
    {% if post.liked %}
        <!-- … -->
    {% endif %}
{% endfor %}

Я нашел ответ здесь, это обходной путь: Шаблон Django как искать значение словаря с помощью переменной

Вернуться на верх