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

如何在Django模板中检查用户是否订阅了对应产品

解决Django模板中判断用户是否订阅产品的问题

问题根源

你尝试的模板代码无法运行,核心原因是Django模板语法不允许在查询集上直接调用带参数的filter()方法(比如request.user.subscriptions_to_product.filter(model_id=content.model_id)),模板仅支持调用无参数的方法或直接访问属性。

解决方案

下面提供两种高效且符合Django规范的实现方式:


方案1:视图预获取订阅ID集合(简单高效)

在视图中提前查询当前用户已订阅的所有MyModels的ID,存入集合后传入模板,模板直接通过in判断即可,避免模板内触发额外数据库查询。

修改users/views.py:

from django.contrib.auth.decorators import login_required
from posts.models import ModelContent, Category, MyModels, Subscription

@login_required(login_url='/user/login')
def homepage(request):
    content = ModelContent.objects.all()
    categorys = Category.objects.all()
    models = MyModels.objects.all()
    suggestions = MyModels.objects.all()[:3]
    
    # 预获取当前用户已订阅的模型ID集合
    subscribed_model_ids = Subscription.objects.filter(
        user=request.user,
        is_subscribed=True
    ).values_list('model__id', flat=True)
    # 转成集合,提升判断效率
    subscribed_model_ids = set(subscribed_model_ids)

    context = {
        "categorys": categorys, 
        "models": models, 
        "content": content, 
        "suggestions": suggestions,
        "subscribed_model_ids": subscribed_model_ids  # 新增变量
    }
    return render(request, 'users/home.html', context)

修改模板代码:

<ul>
{% for content in content %}
    {% if content.model.is_premium %}
        {% if content.model.id in subscribed_model_ids %}
            <li>User Subscribed</li>
        {% else %}
            <li>User Not Subscribed</li>
        {% endif %}
    {% else %}
        <li>Not premium</li>
    {% endif %}
{% endfor %}
</ul>

方案2:使用annotate和Exists子查询(数据库层面高效处理)

通过Django ORM的注解功能,在获取ModelContent时直接为每个对象添加user_is_subscribed属性,一次性完成所有判断,彻底避免N+1查询问题。

修改users/views.py:

from django.contrib.auth.decorators import login_required
from django.db.models import Exists, OuterRef
from posts.models import ModelContent, Category, MyModels, Subscription

@login_required(login_url='/user/login')
def homepage(request):
    # 子查询:判断当前用户是否订阅该模型
    subscription_subquery = Subscription.objects.filter(
        user=request.user,
        model=OuterRef('model'),
        is_subscribed=True
    )
    
    # 为ModelContent添加user_is_subscribed注解
    content = ModelContent.objects.annotate(
        user_is_subscribed=Exists(subscription_subquery)
    )
    
    categorys = Category.objects.all()
    models = MyModels.objects.all()
    suggestions = MyModels.objects.all()[:3]

    context = {
        "categorys": categorys, 
        "models": models, 
        "content": content, 
        "suggestions": suggestions
    }
    return render(request, 'users/home.html', context)

修改模板代码:

<ul>
{% for content in content %}
    {% if content.model.is_premium %}
        {% if content.user_is_subscribed %}
            <li>User Subscribed</li>
        {% else %}
            <li>User Not Subscribed</li>
        {% endif %}
    {% else %}
        <li>Not premium</li>
    {% endif %}
{% endfor %}
</ul>

补充说明

  • 两种方案都规避了模板内执行数据库查询的问题,其中方案2通过一次查询完成所有判断,性能最优;
  • 建议给Subscription模型添加唯一约束(比如UniqueConstraint(fields=['user', 'model'], name='unique_user_model_subscription')),避免生成重复的订阅记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 01:20:34