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

如何将Python计时器项目集成到Django并关联HTML页面

将Python计时器集成到Django的分步指南

1. 调整计时器逻辑适配Web环境

原命令行代码依赖input()和本地线程,需改成接收前端参数的形式,同时移除系统通知(后端无法触发客户端系统通知,改用浏览器通知)。在你的Django应用(比如新建timer_app)的views.py中编写处理逻辑:

import time
from django.shortcuts import render
from django.http import JsonResponse

def calculate_end_time(hours, minutes):
    # 计算总秒数与结束时间
    total_seconds = hours * 3600 + minutes * 60
    end_timestamp = time.time() + total_seconds
    return {
        'total_seconds': total_seconds,
        'end_time': time.ctime(end_timestamp),
        'end_timestamp': end_timestamp
    }

def timer_view(request):
    if request.method == 'POST':
        # 接收前端传入的时间参数
        try:
            hours = int(request.POST.get('hours', 0))
            minutes = int(request.POST.get('minutes', 0))
            if hours < 0 or minutes < 0 or (hours == 0 and minutes == 0):
                return JsonResponse({'error': '无效的时间输入'}, status=400)
            
            time_data = calculate_end_time(hours, minutes)
            return JsonResponse(time_data)
        except ValueError:
            return JsonResponse({'error': '请输入有效数字'}, status=400)
    # GET请求返回计时器页面
    return render(request, 'timer/timer.html')

2. 创建前端HTML页面

在timer_app/templates/timer/目录下(需先创建templates和timer子文件夹)新建timer.html,实现输入表单、倒计时显示与通知功能:

<!DOCTYPE html>
<html>
<head>
    <title>Django计时器</title>
    <style>
        .timer-container {
            max-width: 400px;
            margin: 50px auto;
            padding: 20px;
            text-align: center;
            font-family: Arial, sans-serif;
        }
        .input-group {
            margin: 15px 0;
        }
        input {
            padding: 8px;
            width: 80px;
        }
        button {
            padding: 10px 25px;
            background-color: #2196F3;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        #countdown {
            font-size: 2.5em;
            margin: 25px 0;
            color: #333;
        }
        #message {
            color: #f44336;
        }
    </style>
</head>
<body>
    <div class="timer-container">
        <h1>设置计时器</h1>
        <div class="input-group">
            <label>小时: </label>
            <input type="number" id="hours" min="0" value="0">
        </div>
        <div class="input-group">
            <label>分钟: </label>
            <input type="number" id="minutes" min="0" value="5">
        </div>
        <button onclick="startTimer()">启动计时器</button>
        <div id="countdown"></div>
        <div id="message"></div>
    </div>

    <script>
        let countdownInterval;

        function startTimer() {
            const hours = parseInt(document.getElementById('hours').value);
            const minutes = parseInt(document.getElementById('minutes').value);

            // 向后端发送请求计算结束时间
            fetch('', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'X-CSRFToken': getCookie('csrftoken')
                },
                body: `hours=${hours}&minutes=${minutes}`
            })
            .then(response => response.json())
            .then(data => {
                if (data.error) {
                    document.getElementById('message').textContent = data.error;
                    return;
                }

                // 初始化倒计时
                let remainingSeconds = data.total_seconds;
                updateCountdown(remainingSeconds);

                // 每秒更新倒计时状态
                countdownInterval = setInterval(() => {
                    remainingSeconds--;
                    if (remainingSeconds <= 0) {
                        clearInterval(countdownInterval);
                        document.getElementById('countdown').textContent = "时间到!";
                        showNotification();
                    } else {
                        updateCountdown(remainingSeconds);
                    }
                }, 1000);
            })
            .catch(error => {
                document.getElementById('message').textContent = '启动计时器失败';
                console.error(error);
            });
        }

        function updateCountdown(seconds) {
            const hours = Math.floor(seconds / 3600);
            const minutes = Math.floor((seconds % 3600) / 60);
            const secs = seconds % 60;
            document.getElementById('countdown').textContent = 
                `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
        }

        function showNotification() {
            if (!("Notification" in window)) {
                alert("当前浏览器不支持桌面通知");
                return;
            }

            if (Notification.permission === "granted") {
                new Notification("休息时间到啦!", {
                    body: `当前时间: ${new Date().toLocaleString()}`,
                });
            } else if (Notification.permission !== "denied") {
                Notification.requestPermission().then(permission => {
                    if (permission === "granted") {
                        showNotification();
                    }
                });
            }
        }

        // 获取Django 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>
</body>
</html>

3. 配置URL路由

  1. 在项目根目录的urls.py中添加应用路由:
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('timer/', include('timer_app.urls')),
]
  1. 在timer_app目录下新建urls.py:
from django.urls import path
from . import views

urlpatterns = [
    path('', views.timer_view, name='timer'),
]

4. 关键说明

  • 为何不用后端线程?:Django是请求-响应模型,后端线程会在请求结束后被销毁,无法持续运行倒计时逻辑。前端用JavaScript倒计时更符合Web应用交互模式,同时减轻后端压力。
  • CSRF令牌:Django默认开启CSRF保护,前端POST请求必须携带令牌,代码中已通过getCookie函数实现获取。
  • 通知功能:改用浏览器通知,因为后端服务器无法直接触发客户端系统通知,浏览器通知需用户提前授权。

运行测试

启动Django开发服务器:

python manage.py runserver

访问http://localhost:8000/timer/,设置时间后点击启动即可看到倒计时,时间到会触发浏览器通知。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 18:20:56