如何捕获浏览器历史清除事件以恢复Django旅行产品可用席位?
解决思路与方案
浏览器没有提供可监听的“清除历史/删除session”事件,所以你想通过捕获该事件触发席位恢复的思路行不通,下面是几个可行的替代方案:
1. 临时占用+超时自动恢复(最可靠)
放弃直接修改available字段,改用临时占用机制避免席位锁死:
- 新建一个
TourCartReservation模型,字段包括:tour:关联旅行团模型(ForeignKey)session_key:存储用户的session ID(CharField)expire_at:临时占用的超时时间(DateTimeField,比如设置为加入购物车后15分钟)
- 用户把旅行团加购物车时,不直接减
available,而是创建一条临时占用记录,同时给用户提示“席位已为你保留15分钟”。 - 用户完成下单后,再正式扣减
available并删除对应临时占用记录。 - 用定时任务(比如
django-crontab或Celery)定期扫描TourCartReservation表,清理过期记录,同时把对应旅行团的available加回。 - 前端可以加个定时器,每隔几分钟发一次续期请求,延长临时占用的超时时间(如果用户还在页面操作)。
2. 结合Session过期机制处理
Django的session默认存在django_session表,自带expire_date字段:
- 用户加购物车时,除了把数据存session,同时在数据库建一条
CartItem记录,关联tour_id和session_key。 - 自定义Django的
clearsessions命令(原命令用来删除过期session),在删除过期session前,先找到对应的CartItem记录,把这些旅行团的available加回,再删除CartItem。 - 也可以用定时任务定期查询过期session,手动处理席位恢复。
3. 页面卸载事件(补充方案)
虽然抓不到清除历史的事件,但可以监听页面关闭/卸载事件,在用户正常关闭浏览器或标签页时发送请求恢复席位:
window.addEventListener('beforeunload', function(event) { // 从session或localStorage获取购物车数据 const cart = JSON.parse(sessionStorage.getItem('cart') || localStorage.getItem('cart')); // 发送POST请求到Django接口 fetch('/restore-tour-seats/', { method: 'POST', headers: { 'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value, 'Content-Type': 'application/json' }, body: JSON.stringify({ cart: cart }), keepalive: true // 确保请求在页面卸载时能发送完成 }); });
- 注意:这个方法不是100%可靠,比如浏览器崩溃、强制关机时不会触发,只能作为前两个方案的补充。
内容的提问来源于stack exchange,提问作者Magomed
相关产品推荐
相关产品推荐

