一、项目背景
在流浪动物救助平台中,用户需要注册、登录后才能提交领养申请。Django 提供了强大的内置认证系统django.contrib.auth,可以快速实现:
用户注册
用户登录
用户注销
登录保护(
@login_required装饰器)
本教程将逐步演示如何在现有 Django 项目中集成用户认证功能。
二、环境准备
2.1 项目结构
animal-rescue-platform/ ├── core/ # 项目配置 │ ├── settings.py │ └── urls.py ├── animals/ # 动物档案应用 │ ├── models.py │ ├── views.py │ └── urls.py ├── adoptions/ # 领养申请应用 ├── shelters/ # 救助站应用 ├── templates/ # 模板文件 │ ├── base.html │ ├── registration/ │ │ ├── login.html │ │ └── register.html ├── static/ # 静态文件 ├── media/ # 上传文件 ├── manage.py └── db.sqlite32.2 技术栈
| 技术 | 版本 | 用途 |
|---|---|---|
| Python | 3.8.10 | 开发语言 |
| Django | 4.2.11 | Web 框架 |
| SQLite | 3.x | 数据库 |
| Bootstrap | 5.3 | 前端样式 |
三、配置 settings.py
3.1 注册应用
在core/settings.py中,确保以下应用已注册:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'animals', 'adoptions', 'shelters', 'accounts', ]3.2 配置模板目录
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR / 'templates'], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]3.3 添加认证配置
在文件末尾添加:
# 用户认证配置 LOGIN_REDIRECT_URL = '/animals/' # 登录成功后跳转 LOGOUT_REDIRECT_URL = '/accounts/login/' # 注销后跳转 LOGIN_URL = '/accounts/login/' # 需要登录时跳转四、配置 URL 路由
4.1 主路由core/urls.py
from django.contrib import admin from django.urls import path, include from django.shortcuts import redirect from django.conf import settings from django.conf.urls.static import static urlpatterns = [ path('', lambda request: redirect('/animals/')), path('admin/', admin.site.urls), path('animals/', include('animals.urls')), path('accounts/', include('django.contrib.auth.urls')), # Django 内置登录/登出 path('accounts/', include('accounts.urls')), # 自定义注册 ] if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)4.2 应用路由animals/urls.py
from django.urls import path from . import views app_name = 'animals' urlpatterns = [ path('', views.home, name='home'), path('list/', views.animal_list, name='list'), path('<int:animal_id>/', views.animal_detail, name='detail'), path('register/', views.register, name='register'), # 注册 URL ]五、创建注册视图
5.1 注册视图函数
在animals/views.py中添加注册视图:
from django.shortcuts import render, redirect from django.contrib.auth.models import User from django.contrib.auth import login as auth_login def register(request): """用户注册功能""" if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') password2 = request.POST.get('password2') # 验证密码是否一致 if password != password2: return render(request, 'registration/register.html', { 'error': '两次输入的密码不一致' }) # 验证用户名是否已存在 if User.objects.filter(username=username).exists(): return render(request, 'registration/register.html', { 'error': '用户名已被注册' }) # 创建新用户(密码自动加密) user = User.objects.create_user(username=username, password=password) # 注册后自动登录 auth_login(request, user) # 跳转到首页 return redirect('/animals/') # GET 请求显示注册表单 return render(request, 'registration/register.html')六、创建模板文件
6.1 基础模板templates/base.html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{% block title %}流浪动物救助平台{% endblock %}</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css"> </head> <body> <nav class="navbar navbar-expand-lg navbar-dark bg-primary"> <div class="container"> <a class="navbar-brand" href="/animals/"> <i class="bi bi-heart-fill text-danger"></i> 流浪动物救助平台 </a> <div class="collapse navbar-collapse"> <ul class="navbar-nav ms-auto"> <li class="nav-item"><a class="nav-link" href="/animals/">首页</a></li> <li class="nav-item"><a class="nav-link" href="/animals/list/">待领养动物</a></li> {% if user.is_authenticated %} <li class="nav-item"> <span class="nav-link text-warning">欢迎,{{ user.username }}</span> </li> <li class="nav-item"> <a class="nav-link" href="{% url 'logout' %}">注销</a> </li> {% else %} <li class="nav-item"> <a class="nav-link" href="{% url 'login' %}">登录</a> </li> <li class="nav-item"> <a class="nav-link" href="{% url 'animals:register' %}">注册</a> </li> {% endif %} </ul> </div> </div> </nav> <main> {% block content %}{% endblock %} </main> <footer class="bg-dark text-white text-center py-4 mt-5"> <div class="container"> <p class="mb-0">© 2024 流浪动物救助平台 | 用爱温暖每一个生命</p> </div> </footer> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script> </body> </html>6.2 登录模板templates/registration/login.html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>用户登录 - 流浪动物救助平台</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body class="bg-light"> <div class="container py-5"> <div class="row justify-content-center"> <div class="col-md-5"> <div class="card shadow"> <div class="card-header bg-primary text-white"> <h4 class="mb-0">用户登录</h4> </div> <div class="card-body"> {% if form.errors %} <div class="alert alert-danger"> 用户名或密码错误,请重试。 </div> {% endif %} <form method="post"> {% csrf_token %} <div class="mb-3"> <label class="form-label">用户名</label> <input type="text" name="username" class="form-control" required> </div> <div class="mb-3"> <label class="form-label">密码</label> <input type="password" name="password" class="form-control" required> </div> <button type="submit" class="btn btn-primary w-100">登录</button> </form> <hr> <p class="text-center mb-0"> 还没有账号?<a href="{% url 'animals:register' %}">立即注册</a> </p> </div> </div> </div> </div> </div> </body> </html>6.3 注册模板templates/registration/register.html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>用户注册 - 流浪动物救助平台</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body class="bg-light"> <div class="container py-5"> <div class="row justify-content-center"> <div class="col-md-5"> <div class="card shadow"> <div class="card-header bg-success text-white"> <h4 class="mb-0">用户注册</h4> </div> <div class="card-body"> {% if error %} <div class="alert alert-danger">{{ error }}</div> {% endif %} <form method="post" action="{% url 'animals:register' %}"> {% csrf_token %} <div class="mb-3"> <label class="form-label">用户名</label> <input type="text" name="username" class="form-control" required> </div> <div class="mb-3"> <label class="form-label">密码</label> <input type="password" name="password" class="form-control" required> </div> <div class="mb-3"> <label class="form-label">确认密码</label> <input type="password" name="password2" class="form-control" required> </div> <button type="submit" class="btn btn-success w-100">注册</button> </form> <hr> <p class="text-center mb-0"> 已有账号?<a href="{% url 'login' %}">立即登录</a> </p> </div> </div> </div> </div> </div> </body> </html>七、使用@login_required保护视图
7.1 保护领养申请页面
在adoptions/views.py中:
from django.contrib.auth.decorators import login_required @login_required def apply_adoption(request, animal_id): """只有登录用户才能提交领养申请""" # 业务逻辑...7.2 工作原理
未登录用户访问
/apply/1/时,自动重定向到LOGIN_URL配置的地址(/accounts/login/)登录成功后,会自动跳转回原页面
八、运行测试
8.1 启动服务器
python manage.py runserver8.2 功能测试
| 功能 | URL | 操作 |
|---|---|---|
| 注册 | http://127.0.0.1:8000/animals/register/ | 填写用户名、密码 |
| 登录 | http://127.0.0.1:8000/accounts/login/ | 输入用户名、密码 |
| 注销 | 点击导航栏"注销"按钮 | 退出登录 |
九、运行截图
9.1 注册页面
9.2 登录页面
9.3 登录后首页
十、MVP 原则说明
本实现遵循 MVP(Minimum Viable Product,最小可行产品)原则:
| 原则 | 实现说明 |
|---|---|
| 核心功能优先 | 只实现注册、登录、注销三个核心功能,不做多余功能 |
| 简洁界面 | 使用 Bootstrap 5 快速搭建简洁表单 |
| 快速迭代 | Django 内置 auth 系统开箱即用,无需从零实现 |
| 可验证 | 所有功能可手动测试验证 |
十一、常见问题及解决
11.1NoReverseMatch: Reverse for 'register' not found
原因:模板中使用了{% url 'register' %},但register路由在animals应用下有命名空间。
解决:改为{% url 'animals:register' %}。
11.2ModuleNotFoundError: No module named 'accounts'
原因:INSTALLED_APPS中未添加accounts应用。
解决:检查并添加。
11.3 注册后未自动登录
原因:注册视图中未调用login()函数。
解决:添加from django.contrib.auth import login as auth_login,并在创建用户后调用auth_login(request, user)。
11.4 密码明文存储
原因:使用了User.objects.create()而不是create_user()。
解决:使用create_user()方法,密码会自动加密。
十二、代码仓库
项目代码已上传至 Gitee:
🔗 https://gitee.com/f23016209/animal-rescue-platform
十三、总结
通过本次实验,成功在流浪动物救助平台中集成了 Django 内置的用户认证系统,实现了:
✅ 用户注册(密码加密存储)
✅ 用户登录(Session 管理)
✅ 用户注销(清除 Session)
✅ 登录状态在导航栏动态显示
✅
@login_required保护页面
Django 的django.contrib.auth模块提供了完整的认证功能,大大简化了开发工作。