从零到一:我的 Django 投票项目实战全记录(从 MySQL 踩坑到 MVT 架构落地)
本文记录了我从环境搭建、数据库踩坑到 Django 项目完整跑通的全过程,适合 Django 初学者参考。
一、项目背景
这是一个基于 Django 5.2.12 开发的投票管理系统,采用经典的 MVT(Model-View-Template) 架构,实现了问题发布、选项投票、后台数据管理等核心功能。
二、环境准备与 MySQL 踩坑实录
1. 数据库连接失败:1045 错误解决
问题描述:使用 Navicat 连接 MySQL 时,提示 1045 - Access denied for user 'root'@'localhost' (using password: YES),密码遗忘导致无法登录。
解决步骤:
-
停止 MySQL 服务按下
Win + R,输入services.msc打开服务列表,找到MySQL80(或对应版本服务名),右键选择「停止」。 -
以无密码模式启动 MySQL打开管理员 PowerShell,执行以下命令:
cd "C:\Program Files\MySQL\MySQL Server 8.0\bin"
.\mysqld --defaults-file="C:\ProgramData\MySQL\MySQL Server 8.0\my.ini" --console --skip-grant-tables --shared-memory
-
看到日志中出现
ready for connections即启动成功,此窗口不要关闭。 -
重置 root 密码新开一个管理员 PowerShell 窗口,执行:
-
cd "C:\Program Files\MySQL\MySQL Server 8.0\bin" .\mysql -u root进入 MySQL 命令行后,执行密码重置语句:
-
USE mysql; UPDATE user SET authentication_string = '' WHERE User = 'root' AND Host = 'localhost'; FLUSH PRIVILEGES; ALTER USER 'root'@'localhost' IDENTIFIED BY '你的新密码'; FLUSH PRIVILEGES; EXIT; -
恢复正常服务回到第一个 PowerShell 窗口,按
Ctrl + C停止临时服务,再在服务列表中重启 MySQL 服务,用新密码即可正常连接。 -
2. Django 数据库配置
在
djangoblog/settings.py中配置 MySQL 连接信息:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'djangoblog', 'USER': 'root', 'PASSWORD': '你的新密码', 'HOST': '127.0.0.1', 'PORT': '3306', } }在 MySQL 中创建项目数据库:
CREATE DATABASE `djangoblog` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;三、核心开发:MVT 架构实践
1. Model(模型层)
文件位置:
polls/models.py核心作用:定义数据库表结构,封装数据操作逻辑。from django.db import models class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField("date published") class Choice(models.Model): question = models.ForeignKey(Question, on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0)执行迁移命令同步数据库:
python manage.py makemigrations python manage.py migrate2. View(视图层)
文件位置:
polls/views.py核心作用:接收请求、处理业务逻辑、调用模板渲染。from django.shortcuts import render, get_object_or_404 from .models import Question def index(request): latest_question_list = Question.objects.order_by("-pub_date")[:5] context = {"latest_question_list": latest_question_list} return render(request, "polls/index.html", context) def detail(request, question_id): question = get_object_or_404(Question, pk=question_id) return render(request, "polls/detail.html", {"question": question}) def vote(request, question_id): # 处理投票逻辑,更新 Choice 票数并重定向 pass3. Template(模板层)
文件位置:
polls/templates/polls/核心作用:编写 HTML 页面,使用 Django 模板语言(DTL)动态渲染数据。index.html示例:{% if latest_question_list %} <ul> {% for question in latest_question_list %} <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li> {% endfor %} </ul> {% else %} <p>No polls are available.</p> {% endif %}4. URL 路由配置
文件位置:
mysite/urls.py核心作用:将 URL 路径映射到对应的视图函数。from django.contrib import admin from django.urls import path, include urlpatterns = [ path('polls/', include('polls.urls')), path('admin/', admin.site.urls), ]四、项目启动与后台管理
1. 创建超级管理员
python manage.py createsuperuser
按照提示设置用户名、邮箱和密码,即可创建管理员账号。
2. 启动开发服务器
python manage.py runserver访问
http://127.0.0.1:8000/admin/,使用创建的管理员账号登录,即可在后台管理投票数据: - 新增 / 编辑 / 删除投票问题和选项
- 查看实时投票数据统计


五、MVT 架构总结
表格
| 模块 | 全称 | 核心职责 | 项目中的作用 |
|---|---|---|---|
| Model | 模型 | 数据层 | 定义数据库表结构,封装数据操作逻辑 |
| View | 视图 | 业务逻辑层 | 接收请求、处理数据、调用模板渲染 |
| Template | 模板 | 表现层 | 编写 HTML 页面,动态展示数据 |
这种架构实现了数据、逻辑、展示的解耦,让代码更易维护、扩展,也符合 Django "batteries included" 的设计哲学。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)