python - 在 Django 项目中添加不同的主题模式
问题描述
我正在尝试在我的 Django 项目中为用户添加主题。用户可以在暗模式和亮模式之间进行选择。
所以在 base.html 中,我将链接设置如下:
<link id="mystylesheet" href="{% static 'css/app-light.css' %}" type="text/css" rel="stylesheet">
<!-- Mode -->
<div id="mode" class="section" style="padding-top: 1rem; padding-bottom: 3rem;text-align: right">
<button onclick="swapStyles('app-light.css')" type="button" class="btn btn-secondary">Light Mode</button>
<button onclick="swapStyles('app-dark.css')" type="button" class="btn btn-dark">Dark Mode</button>
</div>
<!-- Mode -->
我已经使用以下 models.py 启动了一个名为 mode 的新应用程序:
class Setting(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="mode",null=True,blank=True)
name = models.CharField(max_length=200, null=True)
value = models.CharField(max_length=200)
def __str__(self):
return self.name
这是javascript
<script type="text/javascript">
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
var cssFile = "{% static 'css' %}"
function swapStyles(sheet){
document.getElementById('mystylesheet').href = cssFile + '/' + sheet
localStorage.setItem('theme', sheet)
updateTheme(sheet)
}
function loadSettings(){
//Call data and set local storage
var url = "{% url 'mode:user_settings' %}"
fetch(url, {
method:'GET',
headers:{
'Content-type':'application/json'
}
})
.then((response) => response.json())
.then(function(data){
console.log('Data:', data)
var theme = data.value;
if (theme == 'light.css' || null){
swapStyles('light.css')
}else if(theme == 'dark.css'){
swapStyles('dark.css')
}
})
}
loadSettings()
function updateTheme(theme){
var url = "{% url 'mode:update_theme' %}"
fetch(url, {
method:'POST',
headers:{
'Content-type':'application/json',
'X-CSRFToken':csrftoken,
},
body:JSON.stringify({'theme':theme})
})
}
</script>
这是 urls.py
app_name = 'mode'
urlpatterns = [
path('user_settings/', views.userSettings, name="user_settings"),
path('update_theme/', views.updateTheme, name="update_theme"),
]
我很难设置用户设置views.py 以反映用户何时登录,但是,更新的主题工作正常。
def userSettings(request):
user = request.user
setting = getattr(user, 'setting', None)
def updateTheme(request):
data = json.loads(request.body)
theme = data['theme']
user = request.user
setting = Setting.objects.update_or_create(
user=user, defaults={'value': theme}, name='theme')
print('Request:', theme)
return JsonResponse('Updated..', safe=False)
我的问题:如何将user settings
当前登录的用户设置为默认设置为亮模式,如果他选择在所有页面的数据库中设置暗模式当它处于暗模式并且用户选择在数据库中设置的亮模式时。
解决方案
您可以这样做的一种方法是;
- 为用户偏好定义模型
- 创建上下文处理器以将首选项传递给您的模板
- 在您的模板中为用户首选项添加一个检查,然后传递定义的
css
然后,您可以在设置更改时强制刷新页面以“应用”新值。
这是一个例子
models.py
class Preferences(models.Model):
themes = (
('light', 'Light Theme'),
('dark', 'Dark Theme'),
)
preference_id = models.AutoField(primary_key=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
theme = models.CharField(max_length=255, choices=themes)
class Meta:
constraints = [
models.UniqueConstraint(fields=['user'], name='One Entry Per User')
]
context processor
from apps.users.models import Preferences
def pref(request):
if request.user.is_authenticated:
_preferences = Preferences.objects.filter(user=request.user).last()
else:
_preferences = None
return {
'user_pref': _preferences,
}
settings.py
TEMPLATES = [
{
'BACKEND': ...,
'DIRS': ...,
'OPTIONS': {
'context_processors': [
'context_processors.user_preferences_context.pref',
],
},
},
]
base.html
{% if user_pref.theme == 'dark' %}
<link href="{% static 'theme/css/themes/layout/header/base/dark.css' %}" rel="stylesheet" type="text/css" />
<link href="{% static 'theme/css/themes/layout/header/menu/dark.css' %}" rel="stylesheet" type="text/css" />
<link href="{% static 'theme/css/themes/layout/brand/dark.css' %}" rel="stylesheet" type="text/css" />
<link href="{% static 'theme/css/themes/layout/aside/dark.css' %}" rel="stylesheet" type="text/css" />
{% else %}
<link href="{% static 'theme/css/themes/layout/header/base/light.css' %}" rel="stylesheet" type="text/css" />
<link href="{% static 'theme/css/themes/layout/header/menu/light.css' %}" rel="stylesheet" type="text/css" />
<link href="{% static 'theme/css/themes/layout/brand/light.css' %}" rel="stylesheet" type="text/css" />
<link href="{% static 'theme/css/themes/layout/aside/light.css' %}" rel="stylesheet" type="text/css" />
{% endif %}
文件结构
project/
-> apps
-> Django Apps stored here
-> context_processors
-> Custom context processors stored here
-> project
-> settings.py
manage.py
推荐阅读
- python - 我可以在一个程序中多次调用函数'main'吗?
- architecture - 是否有架构路线图、流程图或图表之类的东西,用于根据项目要求何时使用某些技术?
- jquery - 如何将日期转换为刚才调用的字符串;x 分钟前;x 天前、x 周前、x 年前等
- php - 使用 PHP MySQLi 从 Google Cloud App Engine 连接到 Cloud SQL 不起作用
- sql - SSRS 在一个实例中运行相同的存储过程多次生成数据集
- xslt - XSLT 1.0 检索或解析特定值
- sql - 转置 Oracle 表/数据集
- javascript - VueJS InvalidValueError:不是 HTMLInputElement 的实例
- python - 如何删除仅位于特定位置的列表元素?
- reactjs - 反应钩子无法清除输入值