如何为Django实现基于登录状态的主题切换?认证用户LocalStorage检查遇阻
Django 主题切换逻辑优化(适配已认证用户)
需求回顾
- 匿名用户:优先读取localStorage中的主题,无值则使用默认light主题(已实现)
- 已认证用户:优先读取localStorage中的主题,无值则使用用户profile里的主题设置(待实现)
解决方案
直接用JS统一处理所有用户的主题逻辑,后端仅负责渲染初始主题类,避免前后端逻辑拆分带来的问题。修改后的模板代码如下:
<body class="{% if user.is_authenticated %}theme-{{ user.profile.theme }}{% else %}theme-light{% endif %}"> <script> // 统一处理所有用户的主题逻辑 const savedTheme = localStorage.getItem('theme'); if (savedTheme) { // 移除当前的主题类 document.body.classList.remove('theme-light', 'theme-dark'); // 应用localStorage里保存的主题 document.body.classList.add(`theme-${savedTheme}`); } </script> <!-- 页面其他内容 -->
逻辑说明
- 后端先给body设置初始主题类:
- 已认证用户:直接使用
user.profile.theme对应的类 - 匿名用户:默认使用
theme-light
- 已认证用户:直接使用
- 页面加载后JS读取localStorage:
- 如果有保存的主题,就替换掉body的初始类
- 没有的话保留后端设置的初始值,完全符合需求
可选:主题切换按钮逻辑
如果需要支持用户手动切换主题,可添加以下交互代码,同时支持将已认证用户的主题同步到后端数据库:
// 假设页面上有个id为theme-toggle的切换按钮 document.getElementById('theme-toggle').addEventListener('click', () => { // 切换当前主题 const isDark = document.body.classList.contains('theme-dark'); const newTheme = isDark ? 'light' : 'dark'; // 更新页面主题类 document.body.classList.remove('theme-light', 'theme-dark'); document.body.classList.add(`theme-${newTheme}`); // 保存到localStorage localStorage.setItem('theme', newTheme); // 已认证用户同步主题到后端 {% if user.is_authenticated %} fetch('/api/save-user-theme/', { method: 'POST', headers: { 'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value, 'Content-Type': 'application/json' }, body: JSON.stringify({ theme: newTheme }) }); {% endif %} });
内容的提问来源于stack exchange,提问作者bigredthelogger
相关产品推荐
相关产品推荐

