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, Username
class 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, UsernameForm
def 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 Http404
usernames = 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 UserCreationForm
def 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开发的核心流程:模型设计、表单处理、视图逻辑、模板渲染、用户认证等。同时,通过中英文版本的实现,理解了多语言应用的基本架构思路。