《Python 实用项目与工具制作指南》· 3.2 实战·开发密码管理器
3.2 实战·开发密码管理器
在本节中,我们将基于Django框架开发一个简易密码管理器,实现用户注册、网站密码存储、中英文切换等核心功能。该项目的完整代码可参考GitHub仓库:https://github.com/yangrenruiyrr/pm。
3.2.1 项目概述与功能设计
核心功能
该密码管理器是一个Web应用,主要帮助用户安全存储不同网站的账号和密码,核心功能包括:
- 用户注册与登录(基于Django内置认证系统)
- 网站信息管理(添加、查看网站)
- 账号密码管理(为网站添加、编辑、查看用户名和密码)
- 中英文双语支持
- 基础的错误处理(404、500页面自动跳转)
技术栈
- 后端:Python 3.x + Django 5.0
- 前端:Bootstrap 5(样式框架)
- 数据库:SQLite(轻量嵌入式数据库,适合小型应用)
- 静态文件处理:Whitenoise
3.2.2 项目结构搭建
初始化项目
- 创建虚拟环境并激活:
python -m venv venv
# Windows激活:venv\Scripts\activate
# Linux/Mac激活:source venv/bin/activate
- 安装依赖:
pip install django==5.0 django-bootstrap5 whitenoise
- 创建项目与应用:
django-admin startproject PM # 项目根目录
cd PM
python manage.py startapp main # 中文主应用
python manage.py startapp accounts # 中文用户认证
python manage.py startapp EN_main # 英文主应用
python manage.py startapp EN_accounts # 英文用户认证
项目目录结构
最终项目结构如下(核心文件):
PM/
├── PM/ # 项目配置目录
│ ├── settings.py # 全局配置
│ ├── urls.py # 主路由
│ └── wsgi.py # WSGI配置
├── main/ # 中文主应用
│ ├── models.py # 数据模型
│ ├── views.py # 视图函数
│ ├── forms.py # 表单定义
│ └── templates/main/ # 中文模板
├── EN_main/ # 英文主应用(结构同main)
├── accounts/ # 中文用户认证(注册等)
├── EN_accounts/ # 英文用户认证(结构同accounts)
├── templates/ # 全局模板(404.html、500.html)
├── static/ # 静态文件(CSS、JS、图片)
└── manage.py # 项目管理脚本
3.2.3 核心配置(settings.py)
在PM/settings.py
中配置项目核心参数,关键配置如下:
# 应用注册(包含中英文应用)
INSTALLED_APPS = ['main','accounts','EN_main','EN_accounts','django_bootstrap5', # Bootstrap支持'django.contrib.admin',# ... 其他内置应用
]# 模板配置(支持全局模板和应用内模板)
TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [BASE_DIR / 'templates'], # 全局模板目录'APP_DIRS': True, # 允许应用内模板# ... 其他配置},
]# 静态文件配置
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfile') # 静态文件收集目录
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' # Whitenoise处理
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')] # 静态文件源目录# 认证配置
LOGIN_REDIRECT_URL = 'main:index' # 登录后跳转首页
LOGOUT_REDIRECT_URL = 'main:index' # 登出后跳转首页
LOGIN_URL = 'accounts:login' # 未登录时跳转的登录页
3.2.4 数据模型设计(models.py)
密码管理器的核心数据是“网站”和“账号密码”,在main/models.py
中定义:
from django.db import models
from django.contrib.auth.models import User # 关联Django内置用户模型class Website(models.Model):"""用户添加的网站(如"GitHub"、"知乎")"""text = models.CharField(max_length=200) # 网站名称date_added = models.DateTimeField(auto_now=True) # 最后修改时间owner = models.ForeignKey(User, on_delete=models.CASCADE) # 关联用户(用户删除时,网站也删除)def __str__(self):return self.text # 打印时显示网站名称class Username(models.Model):"""网站对应的账号密码"""website = models.ForeignKey(Website, on_delete=models.CASCADE) # 关联网站(网站删除时,账号也删除)text = models.CharField(max_length=200) # 用户名text2 = models.CharField(max_length=200) # 密码date_added = models.DateTimeField(auto_now=True) # 最后修改时间def __str__(self):return f"Username:{self.text}\nPassword:{self.text2}" # 打印时显示账号密码
定义完成后执行数据库迁移:
python manage.py makemigrations main # 生成迁移文件
python manage.py migrate # 应用迁移
3.2.5 表单设计(forms.py)
使用Django的ModelForm
快速生成表单,在main/forms.py
中定义:
from django import forms
from .models import Website, Usernameclass WebsiteForm(forms.ModelForm):"""添加网站的表单"""class Meta:model = Website # 关联Website模型fields = ['text'] # 仅包含网站名称字段labels = {'text': ''} # 不显示字段标签class UsernameForm(forms.ModelForm):"""添加账号密码的表单"""class Meta:model = Username # 关联Username模型fields = ['text', 'text2'] # 包含用户名(text)和密码(text2)labels = {'text': '', 'text2': ''} # 不显示字段标签
3.2.6 视图函数实现(views.py)
视图函数处理用户请求并返回响应,以main/views.py
为例,核心逻辑包括:
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required # 登录验证装饰器
from django.http import Http404
from .models import Website, Username
from .forms import WebsiteForm, UsernameFormdef index(request):"""首页视图"""return render(request, 'main/index.html')def help(request):"""帮助页视图"""return render(request, 'main/help.html')@login_required # 仅登录用户可访问
def websites(request):"""网站列表页(显示当前用户的所有网站)"""websites = Website.objects.filter(owner=request.user).order_by('date_added')context = {'websites': websites}return render(request, 'main/websites.html', context)@login_required
def website(request, website_id):"""网站详情页(显示该网站的所有账号密码)"""website = Website.objects.get(id=website_id)# 权限验证:确保用户只能访问自己的网站if website.owner != request.user:raise Http404usernames = website.username_set.order_by('-date_added') # 按时间倒序context = {'website': website, 'usernames': usernames}return render(request, 'main/website.html', context)@login_required
def new_website(request):"""添加新网站"""if request.method != 'POST':# GET请求:显示空表单form = WebsiteForm()else:# POST请求:处理表单数据form = WebsiteForm(data=request.POST)if form.is_valid():new_website = form.save(commit=False) # 暂不保存到数据库new_website.owner = request.user # 设置所属用户new_website.save() # 保存return redirect('main:websites') # 跳转到网站列表context = {'form': form}return render(request, 'main/new_website.html', context)# 其他视图:new_username(添加账号密码)、edit_username(编辑账号密码)
# 逻辑类似,需注意权限验证(仅允许所有者操作)
3.2.7 用户认证(注册功能)
使用Django内置的UserCreationForm
实现注册功能,在accounts/views.py
中:
from django.shortcuts import render, redirect
from django.contrib.auth import login
from django.contrib.auth.forms import UserCreationFormdef register(request):"""用户注册"""if request.method != 'POST':# GET请求:显示空注册表单form = UserCreationForm()else:# POST请求:处理注册数据form = UserCreationForm(data=request.POST)if form.is_valid():new_user = form.save() # 创建用户login(request, new_user) # 自动登录return redirect('main:index') # 跳转到首页context = {'form': form}return render(request, 'registration/register.html', context)
英文注册功能在EN_accounts/views.py
中实现,逻辑相同,仅模板和跳转路由不同。
3.2.8 模板开发(前端页面)
使用模板继承减少重复代码,以中文基础模板main/templates/main/base.html
为例:
<!doctype html>
<html lang="zh-CN">
<head>{% load static %} <!-- 加载静态文件 --><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>密码管理器 V1.1.2</title><link rel="icon" href="/static/image/favicon.ico"> <!-- 网站图标 --><!-- 引入Bootstrap CSS --><link crossorigin="anonymous" href="/static/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" rel="stylesheet"><!-- 引入Bootstrap JS --><script crossorigin="anonymous" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" src="/static/js/bootstrap.min.js"></script>
</head>
<body><!-- 导航栏 --><nav class="navbar navbar-expand-md navbar-light bg-light mb-4 border"><div class="container-fluid"><a class="navbar-brand" href="/">密码管理器 V1.1.2</a><!-- 移动端菜单按钮 --><button class="navbar-toggler" type="button" data-bs-toggle="collapse"data-bs-target="#navbarCollapse" aria-controls="navbarCollapse"aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button><!-- 导航菜单 --><div class="collapse navbar-collapse" id="navbarCollapse"><ul class="navbar-nav me-auto mb-2 mb-md-0"><li class="nav-item"><a class="nav-link" href="/websites/">网站</a></li><li class="nav-item"><a class="nav-link" href="/help/">帮助</a></li></ul></div></div></nav><!-- 页面内容(由子模板填充) --><div class="container">{% block page_header %}{% endblock page_header %}{% block content %}{% endblock content %}</div>
</body>
</html>
子模板(如首页index.html
)通过extends
继承基础模板,并填充内容:
{% extends 'main/base.html' %}
{% block page_header %}<div class="p-3 mb-4 bg-light border rounded-3"><div class="container-fluid py-4"><h1 class="display-3">保管你的密码</h1><p class="lead">登记需要保管密码的网站,并登记用户名和密码。</p><a class="btn btn-primary btn-lg mt-1" href="{% url 'accounts:register' %}">注册 »</a></div></div>
{% endblock page_header %}
3.2.9 中英文国际化支持
通过创建独立的英文应用(EN_main
、EN_accounts
)和模板实现双语支持:
- 英文模板放在
EN_main/templates/EN_main/
目录,如EN_main/templates/EN_main/index.html
- 英文路由独立配置(如
/EN
对应英文首页,/EN/websites/
对应英文网站列表) - 视图逻辑复用,仅模板和跳转路径不同(如英文注册后跳转到英文首页)
3.2.10 错误处理
自定义404和500错误页面(templates/404.html
、templates/500.html
),实现自动跳转:
<!-- 404.html -->
<!doctype html>
<html lang="en">
<head>{% load static %}<meta charset="utf-8"><title>密码管理器</title><!-- 3秒后自动跳转到首页 --><script language="javascript">setTimeout("javascript:location.href='/'", 3000);</script><!-- 引入Bootstrap资源(同基础模板) -->
</head>
<body><!-- 导航栏(同基础模板) --><div class="container"><h1>404 - 页面未找到</h1><p>3秒后自动返回首页...</p></div>
</body>
</html>
3.2.11 运行与测试
- 创建超级用户(可选,用于管理后台):
python manage.py createsuperuser
- 启动开发服务器:
python manage.py runserver
- 访问测试:
- 首页:http://127.0.0.1:8000/
- 英文首页:http://127.0.0.1:8000/EN/
- 管理后台:http://127.0.0.1:8000/admin/
3.2.12 项目扩展方向
-
安全性增强:
- 密码加密存储(当前明文存储,可使用Django加密工具或第三方库如
cryptography
) - 添加CSRF保护(已通过Django内置中间件实现)
- 登录验证码
- 密码加密存储(当前明文存储,可使用Django加密工具或第三方库如
-
功能扩展:
- 密码生成器(自动生成强密码)
- 数据导出/导入(如CSV格式)
- 密码过期提醒
-
体验优化:
- 密码显示/隐藏切换
- 搜索功能(按网站名称搜索)
- 响应式布局优化
通过本项目,我们掌握了Django Web开发的核心流程:模型设计、表单处理、视图逻辑、模板渲染、用户认证等。同时,通过中英文版本的实现,理解了多语言应用的基本架构思路。