使用 Django 框架的投票系统项目

2025年5月18日 | 阅读 17 分钟

Django 框架简介

高级 Python Web 框架 Django 允许开发人员快速创建安全的 Web 应用程序,并且可以根据需要进行扩展。该框架旨在通过允许开发人员重用常用组件以及提供简化应用程序逻辑编程复杂过程的工具来改进 Web 开发。

Django 的主要特点

  1. MTV 架构
    Django 实现了与 MVC(Model-View-Controller)同等流行的 Model-Template-View (MTV) 设计模式。
    1. Model(模型): 管理数据和数据库交互。
    2. Template(模板): 处理表示层以及 HTML 或其他格式的数据渲染。
    3. View(视图): 包含业务逻辑,并连接模型和模板。
  2. ORM (对象关系映射)
    1. 通过其 ORM 功能,Django 允许开发人员使用 Python 类和方法访问数据库,而无需编写 SQL 语句。
    2. 通过其数据库功能,该系统提供了与 PostgreSQL、MySQL、SQLite 和 Oracle 数据库同时工作的机制,同时支持自动数据库更改。
  3. 内置管理界面
    1. Django 提供了一个自动生成、可自定义的管理界面,用于管理应用程序数据和模型。
  4. 可伸缩性和可重用性
    1. Django 中的应用程序是模块化的,允许开发人员在多个项目中重用它们。
    2. 其设计支持创建可伸缩的应用程序。
  5. 安全性
    1. Django 中的内置功能可保护应用程序免受 Web 漏洞的侵害,包括 SQL 注入、点击劫持、XSS(跨站脚本攻击)和 CSRF(跨站请求伪造)。
  6. URL 路由
    1. Django 允许使用正则表达式或路径转换器创建清晰直观的 URL 模式。

为什么选择 Django?

  1. 快速开发: 该框架通过简化重复任务,使开发人员能够采用 DRY(Don't Repeat Yourself,不要重复自己)的方法。
  2. 通用性: 适用于小型项目以及大型系统,如内容管理系统、社交网络和电子商务平台。
  3. 活跃的社区: 由于 Django 庞大的开发者参与基础,提供了频繁的更新、众多的插件和强大的文档。
  4. 跨平台: 可在任何支持 Python 的平台上运行。

实际用例

Django 支持许多知名网站和平台,例如

  1. Instagram
  2. Pinterest
  3. Spotify
  4. Mozilla
  5. 国家地理

投票系统项目概述

通过实现 Django,一个名为投票系统项目的在线应用程序允许注册用户通过提交选票来参与投票。用户可以通过先进行注册,然后登录来访问这个交互式系统,查看可用投票并做出他们的投票选择。该系统赋予管理员完全控制权来创建、管理、更新和删除投票,而所有用户只能查看可用投票和结果,因为他们无法修改它们。每个用户通过系统的安全投票机制,只能参与每个投票一次。

该项目展示了 Django 开发在安全的多功能 Web 应用程序中的实际应用,并遵循了 Web 开发的最佳实践。

投票系统项目目标

主要目标

  • 开发一个功能齐全且用户友好的投票系统。
  • 确保安全的投票机制,用户每个投票只能投一次票。
  • 提供投票的实时结果。
  • 通过管理面板轻松管理投票。

教育目标

  • 演示 Django 在开发全栈 Web 应用程序中的应用。
  • 展示使用 Django ORM 进行数据库设计和关系。
  • 实现身份验证和基于角色的访问控制。
  • 强调部署安全可伸缩 Web 应用程序的最佳实践。

要实现的功能

用户功能

  • 用户注册和身份验证
    • 用户可以注册并登录以访问投票系统。
    • 使用 Django 的身份验证系统安全地存储密码。
  • 查看活动投票
    • 用户可以在定义的开始和结束日期内浏览和查看正在进行的投票。
  • 对投票进行投票
    • 用户可以对任何活动的投票进行投票。
    • 确保用户每个投票只能投一次票。
  • 查看结果
    • 用户可以在投票后或投票结束时查看实时结果。

管理员功能

  • 投票管理
    • 管理员可以创建、更新和删除投票。
    • 为投票添加多个选项。
    • 指定投票的开始和结束日期。
  • 用户管理
    • 管理员可以管理用户帐户(查看、编辑或删除用户)。
  • 结果监控
    • 管理员可以详细监控投票结果(例如,每个选项的投票数)。

高级功能(可选)

  • 搜索和过滤: 用户可以按主题或类别搜索或过滤投票。
  • 实时结果: 使用 Django Channels 或 WebSockets 实现结果的实时更新。
  • 电子邮件通知: 通过电子邮件通知用户新投票。
  • 图表结果: 使用饼图或条形图等图形表示形式显示结果。

理解项目需求

功能需求

  • 用户注册和身份验证
    • 用户必须能够注册、登录和注销。
    • 密码应加密并安全存储。
  • 投票管理
    • 管理员可以创建带有标题、描述和多个选项的投票。
    • 管理员可以设置投票的开始和结束日期。
    • 投票在结束日期后自动过期。
  • 投票机制
    • 用户可以为每个投票选择一个选项进行投票。
    • 用户不能对已过期或未来的投票进行投票。
    • 用户每个投票只能投一次票。
  • 结果显示
    • 用户和管理员可以实时查看结果。
    • 结果应显示每个选项的投票数和百分比。
  • 管理面板
    • 提供用户友好的管理面板来管理投票和用户。

设置

安装 Python

Django 是一个基于 Python 的框架,因此您需要安装 Python 3.8 或更高版本。

检查 Python 是否已安装(在终端或命令提示符中运行)

如果未安装,请从以下网址下载并安装 Python:

https://pythonlang.cn/downloads/。

确保 pip(Python 包安装程序)已安装

安装 Django

安装 Python 后,使用 pip 安装 Django

验证 Django 安装

设置虚拟环境

虚拟环境允许您为 Django 项目创建独立的 Python 环境。

创建虚拟环境

导航到要存储项目的目录并运行

或(macOS/Linux)

激活虚拟环境

Windows

macOS/Linux

激活后,您应该会在终端提示符前看到 (myenv)。

在虚拟环境中安装 Django

在激活虚拟环境后,安装 Django

创建 Django 项目和应用

创建 Django 项目

Django 项目是 Web 应用程序的设置和配置的集合。

运行

这将创建一个 voting_system/ 文件夹,其中包含

导航到项目目录

运行开发服务器

检查 Django 是否正常工作

您将看到类似以下的输出:Starting development server at http://127.0.0.1:8000/

在浏览器中访问 http://127.0.0.1:8000/。

创建 Django 应用

Django 项目包含应用,它们处理特定的功能。要创建一个名为 polls(用于处理投票逻辑)的应用

这将创建一个 polls/ 文件夹

Django 的项目结构

Django 项目包含以下内容:

项目级文件

  • Manage.py:用于管理项目的命令行实用程序(例如,运行服务器、迁移)。
  • Settings.py:配置文件(例如,数据库设置、已安装的应用、中间件)。
  • urls.py:定义用于路由用户请求的 URL 模式。
  • Wsgi.py:使用 WSGI(Web 服务器网关接口)部署应用程序的入口点。
  • Asgi.py:部署异步服务器的入口点。

应用级文件(在 polls/ 文件夹内)

  • Models.py:定义数据库模型(例如,Poll、Vote、Option)。
  • Views.py:处理业务逻辑并返回 HTTP 响应。
  • Urls.py:将 URL 映射到视图(需要在每个应用中创建)。
  • Admin.py:将模型注册到 Django 的内置管理面板。
  • Migrations/:存储数据库迁移文件。
  • Tests.py:包含应用的测试用例。

后续步骤

在 settings.py 中将 polls 应用添加到 INSTALLED_APPS

运行数据库迁移

为投票、选项和投票定义模型

投票模型

Poll 模型代表一个投票/问题。

选项模型

Option 模型存储每个投票的答案选项。

投票模型

Vote 模型记录了哪个用户为哪个选项投票。

建立模型之间的关系

一对多关系(ForeignKey)

  • 一个投票有多个选项(Poll → Option)。
  • 一个用户可以创建多个投票(User → Poll)。
  • 一个用户每个投票只能投一次票(User → Vote)。

确保投票完整性的约束

  • 用户不能在同一个投票中多次投票(Vote 模型中的 unique_together)。
  • 删除投票时;其所有关联的选项和投票也应被删除(on_delete=models.CASCADE)。

运行迁移以创建数据库架构

进行迁移

运行以下命令生成迁移文件

应用迁移

运行

这将为我们的模型创建数据库表。

在 Django 管理中注册模型

要通过 Django 的管理面板管理投票、选项和投票,请在 polls/admin.py 中注册它们。

运行开发服务器

然后,访问 http://127.0.0.1:8000/admin/ 来管理模型。

为投票系统编写 Django 视图

Voting System Project Using Django Framework

Django 视图处理用户请求和响应。我们将创建以下视图:

  • 列出投票
  • 显示投票详情和选项
  • 捕获投票
  • 显示投票结果

设置 URL

在编写视图之前,请在 polls 应用中创建 urls.py 文件。

为投票系统编写 Django 视图

在 views.py 中编写视图

列出投票

此视图检索所有活动的投票并显示它们。

说明

  • 检索 start_date 在过去且 end_date 在未来的投票。
  • 渲染 poll_list.html,传入投票列表。

显示投票详情和选项

此视图获取一个投票及其选项。

说明

  • 确保投票存在且处于活动状态。
  • 使用关联名称 "options" 获取投票选项(在模板中使用 poll.options.all())。
  • 在 poll_detail.html 中显示投票详情。

捕获投票

用户每个投票只能投一次票。

说明

  • 检查投票是否存在且处于活动状态。
  • 确保用户已通过身份验证。
  • 使用 Vote.objects.filter(poll = poll, user = request.user).exists() 防止多次投票。
  • 存储选定的选项。
  • 投票后重定向到投票结果页面。

显示投票结果

此视图显示每个选项的投票数。

说明

  • 使用 annotate(vote_count=models.Count('vote')) 为每个选项计数投票。
  • 将投票及其聚合投票结果传递给 poll_results.html。

在投票系统中使用的 Django 模板

Django 模板允许我们使用来自视图的数据动态生成 HTML 页面。以下是我们组织模板的方式:

模板功能

  • 使用 base.html 作为可重用的基本模板。
  • 使用 {% extends %} 和 {% include %} 进行模块化设计。
  • 动态显示投票、选项和结果。
  • 添加用于投票和创建投票的表单(供管理员使用)。
  • 使用 Bootstrap 进行样式设计,以获得响应式 UI。

创建可重用的基本模板 (base.html)

此模板为所有页面提供一致的布局。包括导航、Bootstrap 和消息。

polls/templates/polls/base.html

列出投票 (poll_list.html)

此页面列出所有活动的投票。

polls/templates/polls/poll_list.html

用途

  • {% for poll in polls %} 用于循环遍历投票。
  • {% url 'poll_detail' poll.id %} 用于创建动态链接。
  • {{ poll.end_date|date:"M d, Y" }} 用于格式化日期。

显示投票详情和投票 (poll_detail.html)

此页面显示投票选项并允许用户投票。

polls/templates/polls/poll_detail.html

显示投票结果 (poll_results.html)

此页面显示每个选项的投票数。

polls/templates/polls/poll_results.html

特点

  • 显示每个选项及其投票数。
  • 使用 {% for option in results %} 和 .annotate(vote_count=models.Count('vote')).

添加投票创建表单(供管理员使用)

只有管理员才能创建投票。我们将使用 Django 表单。

在 forms.py 中定义表单

投票创建视图 (views.py)

投票创建模板 (create_poll.html)

Django 投票系统的管理端功能

管理面板对于高效管理投票至关重要。在本指南中,我们将:

  • 启用 Django Admin 以管理投票。
  • 创建、更新和删除投票。
  • 为投票添加选项。
  • 自定义管理界面以提高可用性。

在 Django Admin 中注册投票

Django 带有一个内置的管理面板,可以通过 /admin/ 访问。

要启用它,请在 admin.py 中注册 Polls、Options 和 Votes。polls/admin.py

from django.contrib import admin

管理员功能

  • 列出投票,包括问题、开始日期、结束日期、创建者。
  • 使用 list_filter 按日期过滤。
  • 使用 search_fields 搜索投票和选项。
  • 按最近排序投票(ordering = ('-start_date',)).

启用投票的创建、编辑和删除

管理员可以通过 Django Admin 创建、更新和删除投票。

  • 访问 /admin/
  • 点击 "添加投票" → 填写详细信息 → 保存
  • 点击任何投票 → 编辑或删除它。

为投票添加选项

与其单独添加投票选项,不如在创建/编辑投票时使用内联表单来添加选项。

修改 polls/admin.py

自定义管理界面

为了使管理界面更用户友好,我们可以:

  • 使用登录的管理员预填充 created_by。
  • 将 created_by 设置为只读,以便管理员不更改它。

修改 polls/admin.py

其中

  • 投票自动分配 created_by 给管理员用户。
  • created_by 为只读,以防止修改。

在 Django 中实现投票逻辑

要实现一个合适的投票系统,我们需要:

  • 记录用户的投票。
  • 限制用户每个投票只能投票一次。
  • 验证用户输入以防止无效投票。

更新投票模型

models.py

主要特点

  • 用户每个投票只能投一次票(通过 Vote 模型中的 unique_together 来强制执行)。
  • 投票包含多个选项,通过 ForeignKey 连接。
  • 投票与用户关联,以跟踪他们的选择。

在视图中实现投票逻辑

views.py

投票逻辑

  • 将投票限制为已登录用户(@login_required)。
  • 使用 Vote.objects.filter() 防止每个投票多次投票。
  • 验证用户输入(确保在投票前选择了选项)。
  • 检查投票是否仍然有效(未过期)。
  • 如果所有条件都满足,则保存投票。

更新用于投票的投票详情模板

修改投票详情页面以允许用户投票。

poll_detail.html

模板功能

  • 仅当用户尚未投票时显示投票表单。
  • 如果用户已投票,则显示一条消息。
  • 投票后链接到结果。

显示投票结果

投票后,用户可以查看实时结果。

views.py

poll_results.html

特点

  • 列出每个选项及其总投票数。
  • 按投票数排序选项(order_by('-vote_count'))。
  • 如果没有投票,则显示一条消息。

使用图表显示已完成投票的结果

为了有效呈现投票结果,我们将:

  • 仅显示已完成投票的结果。
  • 计算并显示投票数和百分比。
  • 使用图表(使用 Chart.js)可视化结果。

更新投票结果视图

我们需要计算每个选项的总投票数并计算百分比。

views.py

特点

  • 仅当投票已完成时显示结果(poll.end_date > timezone.now())。
  • 计算总投票数以进行百分比计算。
  • 防止除以零。

创建投票结果页面

我们将以表格和条形图的形式显示结果。

poll_results.html

Voting System Project Using Django Framework
Voting System Project Using Django Framework

特点

  • 显示投票数和百分比的表格。
  • 使用 Chart.js 的条形图可视化。
  • 正确处理投票数为零的投票。

优点

  1. 可伸缩性和性能: Django 高度可伸缩,适用于小型调查和大型选举。使用优化的数据库查询(通过 Django ORM)来实现快速的投票计数和结果显示。
  2. 安全性: 内置的用户身份验证可防止未经授权的投票。CSRF 保护有助于防止投票被篡改。唯一投票约束确保用户不能多次投票。
  3. 快速开发: Django 的内置功能(如管理面板、模型、表单)可缩短开发时间。可重用的模板和视图可加快 UI 设计速度。
  4. 数据库管理: Django ORM 简化了关系数据库中投票、选项和投票的处理。迁移使模式更改变得容易。
  5. 可定制性: 可以扩展以支持实时投票更新、多阶段选举或排序选择投票。Django 管理面板允许轻松创建和管理投票。

缺点

  1. 对初学者的复杂性: Django 的学习曲线陡峭(ORM、视图、表单、身份验证)。新开发人员可能会在设置模型、迁移和关系方面遇到困难。
  2. 实时选举的可伸缩性挑战: 不适合大规模实时投票(例如,每秒数百万次投票)。对于高流量投票,需要缓存(Redis、Memcached)或异步处理(Celery、Django Channels)。
  3. 数据库约束: 关系数据库在存储数百万次投票时可能会变慢。可能需要数据库索引和查询优化以提高性能。
  4. 前端限制: Django 的默认模板引擎不如 React、Vue 或 Angular 现代化。要构建动态投票 UI,建议与 AJAX、JavaScript 或前端框架集成。
  5. 无内置实时功能: 如果需要实时投票更新,Django 需要 WebSockets 或 Django Channels(需要额外设置)。

下一主题Flask 教程