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

如何在Django中点击切换开关保存布尔字段值?

问题描述

我是开发新手,正尝试点击切换开关将其值保存到Django的布尔字段is_active中。已完成以下配置:

home.html

<style>
    .home-container{
display:grid;
grid-template-columns: 1fr 4fr;
}

.switch {
  position: relative;
  display: inline-block;
  width: 60px;
  height: 34px;
}

.switch input { 
  opacity: 0;
  width: 0;
  height: 0;
}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  -webkit-transition: .4s;
  transition: .4s;
}

.slider:before {
  position: absolute;
  content: "";
  height: 26px;
  width: 26px;
  left: 4px;
  bottom: 4px;
  background-color: white;
  -webkit-transition: .4s;
  transition: .4s;
}

input:checked + .slider {
  background-color: #2196F3;
}

input:focus + .slider {
  box-shadow: 0 0 1px #2196F3;
}

input:checked + .slider:before {
  -webkit-transform: translateX(26px);
  -ms-transform: translateX(26px);
  transform: translateX(26px);
}

/* Rounded sliders */
.slider.round {
  border-radius: 34px;
}

.slider.round:before {
  border-radius: 50%;
} 
    
</style>


   <div>
      <label class="switch">
 <input type="checkbox" checked>
  <span class="slider round"></span>
</label>
    </div>

models.py

is_active = models.BooleanField(default=False) 

urls.py

path('engine/', views.engine, name="engine"),

尝试了网上多种方案均未成功,已知需要使用JavaScript,请求帮助编写views.py代码以及home.html中的JavaScript代码。


解决方案

1. views.py 代码

假设你要更新的是MyModel模型的实例,视图需处理GET和POST请求:

from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .models import MyModel

@csrf_exempt  # 开发阶段临时使用,生产环境需移除并使用CSRF令牌
def engine(request):
    if request.method == 'POST':
        is_active = request.POST.get('is_active') == 'true'
        # 按业务需求调整实例查询条件,这里以id=1为例
        try:
            obj = MyModel.objects.get(id=1)
            obj.is_active = is_active
            obj.save()
            return JsonResponse({'status': 'success', 'is_active': is_active})
        except MyModel.DoesNotExist:
            return JsonResponse({'status': 'error', 'message': '对象不存在'}, status=404)
    elif request.method == 'GET':
        try:
            obj = MyModel.objects.get(id=1)
            return JsonResponse({'is_active': obj.is_active})
        except MyModel.DoesNotExist:
            return JsonResponse({'is_active': False})
    return JsonResponse({'status': 'error', 'message': '不支持的请求方法'}, status=400)

2. 修改后的 home.html

给开关添加ID、初始化状态,并编写JavaScript处理切换事件:

<style>
    .home-container{
display:grid;
grid-template-columns: 1fr 4fr;
}

.switch {
  position: relative;
  display: inline-block;
  width: 60px;
  height: 34px;
}

.switch input { 
  opacity: 0;
  width: 0;
  height: 0;
}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  -webkit-transition: .4s;
  transition: .4s;
}

.slider:before {
  position: absolute;
  content: "";
  height: 26px;
  width: 26px;
  left: 4px;
  bottom: 4px;
  background-color: white;
  -webkit-transition: .4s;
  transition: .4s;
}

input:checked + .slider {
  background-color: #2196F3;
}

input:focus + .slider {
  box-shadow: 0 0 1px #2196F3;
}

input:checked + .slider:before {
  -webkit-transform: translateX(26px);
  -ms-transform: translateX(26px);
  transform: translateX(26px);
}

/* Rounded sliders */
.slider.round {
  border-radius: 34px;
}

.slider.round:before {
  border-radius: 50%;
} 
    
</style>

<div>
    <label class="switch">
        <!-- 用模板变量初始化开关状态,替换为你实际的对象变量 -->
        <input type="checkbox" id="active-switch" {% if object.is_active %}checked{% endif %}>
        <span class="slider round"></span>
    </label>
</div>

<script>
document.addEventListener('DOMContentLoaded', function() {
    const switchInput = document.getElementById('active-switch');
    
    switchInput.addEventListener('change', function() {
        const isActive = this.checked;
        
        fetch('{% url "engine" %}', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
                'X-CSRFToken': getCookie('csrftoken')
            },
            body: `is_active=${isActive}`
        })
        .then(response => response.json())
        .then(data => {
            if (data.status !== 'success') {
                // 更新失败时恢复原状态
                switchInput.checked = !isActive;
                console.error('更新失败:', data.message);
            }
        })
        .catch(error => {
            switchInput.checked = !isActive;
            console.error('请求出错:', error);
        });
    });
    
    // 获取CSRF令牌的辅助函数
    function getCookie(name) {
        let cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            const cookies = document.cookie.split(';');
            for (let i = 0; i < cookies.length; i++) {
                const cookie = cookies[i].trim();
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
});
</script>

注意事项

  • 将代码中的MyModel替换为你实际使用的模型类,实例查询条件(如id=1)需根据业务调整
  • 生产环境务必移除@csrf_exempt,确保JS中正确携带CSRF令牌
  • 确保模板能获取到object变量(或自定义变量名)来初始化开关状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 03:21:02