【问题标题】:why the {% if post.is_liked %} doesn't work in home.html为什么 {% if post.is_liked %} 在 home.html 中不起作用
【发布时间】:2020-06-21 02:25:48
【问题描述】:

我已将 is_liked 的上下文从 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 %}

【问题讨论】:

  • 因为你没有在帖子上分配这些。您只是创建了一个包含一个变量is_liked的上下文,因此post.is_liked不存在,只有is_liked,这与特定帖子无关。
  • 如果我想在特定帖子中分配 is_liked 应该怎么做?因为我已经对 PostDetailView 做了这个,它工作得很好,因为 detailview 只是显示了一个特定的帖子。但是在主页视图中,我不知道如何分配它。谢谢
  • 发布相关模型...
  • 抱歉,我已经添加了相关型号

标签: python python-3.x django django-rest-framework django-views


【解决方案1】:

您可以注释查询集,以便由此产生的 Post 对象具有额外的属性 .is_liked 和 Exists subquery [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')
            ))
        )

【讨论】:

  • 谢谢,但我收到了错误NameError at / name 'request' is not defined 为什么会这样?
  • @LouisGlenn:是的,请求对象是self的一个属性,所以self.request.user.id。
猜你喜欢
  • 2011-04-10
  • 1970-01-01
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
  • 2014-01-17
  • 1970-01-01
  • 2022-12-04
  • 2023-01-26
相关资源
最近更新 更多