You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django模板中无法判断当前用户是否收藏分页Recipe的问题

问题分析与解决

1. 拼写错误导致的基础问题

你的Recipe模型里多对多字段叫favourites(英式拼写),但模板里写的是recipe.favorites(美式拼写),这是第一个直接错误,先修正这个拼写问题。

2. 多对多字段的模板判断逻辑问题

即使修正拼写,recipe.favourites是Django的多对多管理器对象,不能直接用request.user.profile.id in recipe.favourites来判断,因为管理器不是可迭代的ID集合。你可以用以下两种方法解决:

方法一:模板内直接判断(适合简单场景,注意性能)

修正拼写后,直接判断用户profile是否在recipe.favourites.all()的结果集中:

{% for recipe in page_obj %}
    {% if request.user.profile in recipe.favourites.all %}
        <button>Recipe added to favourites</button>
    {% else %}
        <button>Add to favourites</button>
    {% endif %}
{% endfor %}

⚠️ 注意:这种方法会对每个Recipe发起额外查询,分页数据较多时会有性能损耗。

方法二:视图中用annotate预计算(推荐,无N+1查询问题)

在ListView的get_queryset里,用Exists子查询提前标注当前用户是否已收藏该食谱,模板直接使用预计算的字段即可:

先导入所需模块:

from django.db.models import Exists, OuterRef

修改你的ListView代码:

class Home(ListView):
    model = Recipe
    template_name = 'home.html'
    paginate_by = 2

    def get_queryset(self):
        queryset = Recipe.objects.order_by('id').prefetch_related('profile__recipecomment_set__recipe')
        
        # 仅当用户登录时,添加收藏状态标注
        if self.request.user.is_authenticated:
            user_profile = self.request.user.profile
            queryset = queryset.annotate(
                is_favourite=Exists(
                    Recipe.favourites.through.objects.filter(
                        recipe_id=OuterRef('pk'),
                        profile_id=user_profile.pk
                    )
                )
            )
        return queryset

然后模板里直接判断预计算的字段:

{% for recipe in page_obj %}
    {% if user.is_authenticated %}
        {% if recipe.is_favourite %}
            <button>Recipe added to favourites</button>
        {% else %}
            <button>Add to favourites</button>
        {% endif %}
    {% else %}
        <button>请登录后收藏</button>
    {% endif %}
{% endfor %}

这种方法只会发起2次查询(一次获取Recipe列表,一次子查询判断所有食谱的收藏状态),性能更优,适合分页场景。

内容的提问来源于stack exchange,提问作者Spica Simpson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 15:45:54