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

Django实现记住我功能同时保留商品浏览量1天去重规则的方案咨询

解决方案

最优方案:无需新增模型,复用现有逻辑即可解决

你完全不需要自定义会话引擎,也不需要修改全局SESSION_COOKIE_AGE,Django原生支持两个核心能力刚好匹配你的需求:

1. 单独设置用户会话过期时间实现「记住我」

全局SESSION_COOKIE_AGE保持默认的86400(1天)即可,只需要在登录视图中加逻辑:

  • 用户未勾选「记住我」:使用默认的1天会话有效期
  • 用户勾选「记住我」:调用request.session.set_expiry(30 * 24 * 60 * 60),单独给该用户的会话设置30天有效期
    这个是Django原生提供的能力,稳定性和默认会话引擎完全一致,不会影响其他功能。

2. 给浏览记录单独加1天过期逻辑,和会话有效期解耦

你原来的逻辑是直接在session里存产品ID数组,所以会跟着会话有效期走,只要稍微修改存储结构就能解决:不要只存ID,给每个ID加访问时间戳,每次访问前先清理超过1天的过期记录即可。
修改后的视图逻辑示例:

import time
def product_detail_view(request, id):
    # 存储结构改成 {产品ID: 访问时间戳},不再是单纯的ID数组
    if 'views' not in request.session:
        request.session['views'] = {}
    views_dict = request.session['views']
    current_time = time.time()
    # 先清理所有超过1天的过期记录
    expired_time = current_time - 86400
    views_dict = {pid: t for pid, t in views_dict.items() if t > expired_time}

    obj = get_object_or_404(Product, id=id)
    id_str = str(id) # session字典的key只能是字符串
    if id_str not in views_dict:
        views_dict[id_str] = current_time
        obj.product_views += 1
        obj.save()
    # 把清理后的字典存回session
    request.session['views'] = views_dict

    context = {
        'object': obj,
    }
    return render(request, 'home/detail.html', context)

这个方案不需要改动任何现有模型,也不需要额外的定时任务,代码改动量极小,稳定性最高。


备选方案:如果你需要持久化浏览记录

如果你后续需要统计用户浏览历史、做推荐等需求,可以使用你自定义的ProductViews模型,只需要做几个优化提升稳定性和性能:

  • 未登录用户的标识不要只用IP,建议将IP + User-Agent做哈希后存入viewer字段,避免同一局域网下多用户被误判为同一访问者
  • 不要每次请求都判断单条记录是否过期,写一个Django定时命令,每天凌晨批量删除所有超过1天的浏览记录,减少数据库查询压力
  • 访问判断用筛选近1天记录的方式减少逻辑复杂度:
    from django.utils import timezone
    from datetime import timedelta
    
    def product_detail_view(request, id):
        obj = get_object_or_404(Product, id=id)
        filter_kwargs = {"product": obj}
        if request.user.is_authenticated:
            filter_kwargs["user"] = request.user
        else:
            # 生成访客标识的逻辑自己实现
            viewer_hash = generate_viewer_hash(request)
            filter_kwargs["viewer"] = viewer_hash
        # 只查近1天的记录即可
        exists = ProductViews.objects.filter(**filter_kwargs, datetime__gte=timezone.now()-timedelta(days=1)).exists()
        if not exists:
            ProductViews.objects.create(**filter_kwargs)
            obj.product_views +=1
            obj.save()
        # 后续逻辑不变
    

内容的提问来源于stack exchange,提问作者Dragon-LV

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 16:45:04