当前位置: 首页 > news >正文

Django 从 0 到 1 打造完整电商平台:登录与登出功能实现


作者:IT策士

10余年一线大厂经验,专注 IT 思维、架构、职场进阶。持续发布最新文章,助你少走弯路。


前言

上一篇我们完成了用户注册功能,数据库里已经积累了一批注册用户。但一个完整的身份认证体系,光有注册是不够的——用户还需要能够登录登出

今天这篇文章,我们将基于 Django 内置的认证系统(django.contrib.auth),通过自定义认证后端实现多方式登录(手机号/邮箱/用户名),同时集成"记住我"、登录后跳转、导航栏状态切换等实用功能。

跟着我的步骤,半小时内让你的项目真正"认人"。


一、需求分析

我们要实现的登录功能清单:

功能点说明
多方式登录支持手机号、邮箱、用户名任一方式登录
错误提示密码错误或用户不存在时给出明确提示
记住我支持延长 session 有效期
导航栏切换登录后显示"欢迎,XXX"及下拉菜单
智能跳转登录后返回之前想访问的页面,否则回首页
安全登出清除 session,回到首页

二、自定义认证后端

2.1 为什么要自定义?

Django 默认的认证后端只能通过usernamepassword登录。但我们的注册逻辑允许用户用手机号或邮箱注册,username字段存储的可能是手机号或邮箱前缀,这会导致用户记不住自己的用户名。

解决方案:自定义认证后端,让系统同时匹配手机号、邮箱和用户名。

2.2 实现代码

apps/users/目录下创建backends.py

from django.contrib.auth.backendsimportModelBackend from django.db.modelsimportQ from .modelsimportUser class MultiFieldAuthBackend(ModelBackend):""" 支持手机号 / 邮箱 / 用户名 登录的自定义认证后端""" def authenticate(self, request,username=None,password=None, **kwargs): try:# 使用 Q 对象进行 OR 查询,同时匹配三个字段user=User.objects.get(Q(username=username)|Q(email=username)|Q(phone=username))except User.DoesNotExist:returnNone# 校验密码(Django 自动处理密码哈希比对)ifuser.check_password(password):returnuserreturnNone

2.3 工作原理

Django 调用authenticate()时会遍历所有配置的认证后端。我们的自定义后端优先尝试匹配手机号、邮箱或用户名,只要用户输入的是三者之一,都能找到对应账户。

2.4 注册后端

django_ecommerce/settings.py中声明:

AUTHENTICATION_BACKENDS=['users.backends.MultiFieldAuthBackend',# 自定义后端(优先)'django.contrib.auth.backends.ModelBackend',# 保留默认后端]

三、登录表单

apps/users/forms.py中追加登录表单:

from djangoimportforms class LoginForm(forms.Form): username=forms.CharField(label='账号',widget=forms.TextInput(attrs={'class':'form-control','placeholder':'手机号 / 邮箱 / 用户名'}))password=forms.CharField(label='密码',widget=forms.PasswordInput(attrs={'class':'form-control','placeholder':'请输入密码'}))remember=forms.BooleanField(label='记住我',required=False,widget=forms.CheckboxInput(attrs={'class':'form-check-input'}))

设计思路:表单只负责收集和基础校验,真正的认证逻辑交给视图处理,保持关注点分离。


四、登录视图

编辑apps/users/views.py,添加登录逻辑:

from django.contrib.authimportauthenticate, login,logoutfrom django.shortcutsimportrender, redirect from django.contribimportmessages from .formsimportLoginForm def user_login(request):# 已登录用户直接重定向到首页ifrequest.user.is_authenticated:returnredirect('home')ifrequest.method=='POST':form=LoginForm(request.POST)ifform.is_valid(): username=form.cleaned_data['username']password=form.cleaned_data['password']remember=form.cleaned_data.get('remember')# 调用自定义后端进行认证user=authenticate(request,username=username,password=password)ifuser is not None:ifuser.is_active:# 执行登录,将用户写入 sessionlogin(request, user)# 处理"记住我"逻辑ifremember:# Session 有效期 30 天request.session.set_expiry(60*60*24*30)else:# 浏览器关闭即失效request.session.set_expiry(0)# 跳转到 next 参数指定的页面,否则回首页next_url=request.GET.get('next','home')messages.success(request, f'欢迎回来,{user.username}!')returnredirect(next_url)else: messages.error(request,'该账号已被禁用,请联系管理员。')else: messages.error(request,'账号或密码错误,请重试。')else: form=LoginForm()returnrender(request,'users/login.html',{'form':form})

核心要点解析

要点说明
request.user.is_authenticated检查用户是否已登录,避免重复登录
authenticate()自动调用我们自定义的MultiFieldAuthBackend
login(request, user)将认证信息写入 session,完成登录
set_expiry()控制 session 有效期,实现"记住我"
next参数Django 内置跳转机制,登录后自动返回原页面

五、登出视图

继续在views.py末尾添加,逻辑非常简单:

def user_logout(request): logout(request)# 清除当前 session 中的所有认证数据messages.success(request,'您已成功退出登录。')returnredirect('home')

六、配置 URL 路由

编辑apps/users/urls.py,追加登录和登出路由:

from django.urlsimportpath from.importviews urlpatterns=[path('register/', views.register,name='register'), path('send_sms/', views.send_sms_code,name='send_sms'), path('activate/<int:user_id>/<str:token>/', views.activate_email,name='activate_email'), path('login/', views.user_login,name='login'), path('logout/', views.user_logout,name='logout'),]

七、登录页面模板

创建apps/users/templates/users/login.html

{% extends'base.html'%}{% block title %}用户登录{% endblock %}{% block content %}<divclass="row justify-content-center"><divclass="col-md-6 col-lg-5"><divclass="card shadow-sm"><divclass="card-body p-4"><h3class="text-center mb-4">🔐 用户登录</h3><formmethod="post"novalidate>{% csrf_token %}<!-- 全局错误提示 -->{%ifform.non_field_errors %}<divclass="alert alert-danger">{{form.non_field_errors.0}}</div>{% endif %}<!-- 账号输入 --><divclass="mb-3"><labelclass="form-label">{{form.username.label}}</label>{{form.username}}{%ifform.username.errors %}<divclass="text-danger small">{{form.username.errors.0}}</div>{% endif %}</div><!-- 密码输入 --><divclass="mb-3"><labelclass="form-label">{{form.password.label}}</label>{{form.password}}{%ifform.password.errors %}<divclass="text-danger small">{{form.password.errors.0}}</div>{% endif %}</div><!-- 记住我 --><divclass="mb-3 form-check">{{form.remember}}<labelclass="form-check-label"for="{{ form.remember.id_for_label }}">{{form.remember.label}}</label></div><buttontype="submit"class="btn btn-primary w-100">登录</button></form><pclass="text-center mt-3">还没有账号?<ahref="{% url 'users:register' %}">立即注册</a></p></div></div></div></div>{% endblock %}

八、更新导航栏(动态切换)

打开templates/base.html,替换导航栏的用户相关部分:

<ulclass="navbar-nav ms-auto"><liclass="nav-item"><aclass="nav-link"href="{% url 'home' %}">首页</a></li><liclass="nav-item"><aclass="nav-link"href="#">商品</a></li><liclass="nav-item"><aclass="nav-link"href="#">购物车</a></li>{%ifuser.is_authenticated %}<!-- 已登录:显示用户下拉菜单 --><liclass="nav-item dropdown"><aclass="nav-link dropdown-toggle"href="#"role="button">="dropdown">👤{{user.username}}</a><ulclass="dropdown-menu dropdown-menu-end"><li><aclass="dropdown-item"href="#">个人中心</a></li><li><aclass="dropdown-item"href="#">我的订单</a></li><li><hrclass="dropdown-divider"></li><li><aclass="dropdown-item"href="{% url 'admin:index' %}">后台管理</a></li><li><aclass="dropdown-item"href="{% url 'users:logout' %}">退出登录</a></li></ul></li>{%else%}<!-- 未登录:显示登录/注册入口 --><liclass="nav-item"><aclass="nav-link"href="{% url 'users:login' %}">登录</a></li><liclass="nav-item"><aclass="nav-link"href="{% url 'users:register' %}">注册</a></li>{% endif %}</ul>

效果:未登录时显示"登录"和"注册",登录后显示用户名下拉菜单,包含个人中心、订单、后台管理、退出登录等入口。


九、完整流程测试

启动开发服务器:

python manage.py runserver

9.1 手机号登录测试

  1. 访问http://127.0.0.1:8000/users/login/

  2. 输入手机号13800138000(上一篇注册的手机号)和密码

  3. 勾选"记住我",点击登录

预期结果:

  • 终端输出302重定向状态码

  • 浏览器跳转到首页

  • 导航栏显示👤 13800138000下拉菜单

  • 页面顶部显示绿色消息:“欢迎回来,13800138000!”

9.2 邮箱登录测试

  1. 点击导航栏"退出登录",确认看到成功提示

  2. 重新进入登录页,输入邮箱test@example.com和密码

  3. 点击登录

预期结果:同样登录成功,验证自定义后端对邮箱的匹配支持。

9.3 错误情况测试

输入错误的密码,页面应显示红色提示:

账号或密码错误,请重试。

终端返回200状态码,表示停留在登录页并展示错误信息。

9.4 登出流程测试

点击"退出登录":

  • 终端输出302重定向

  • 回到首页,导航栏恢复为"登录"和"注册"

  • 页面显示绿色消息:“您已成功退出登录。”


十、未登录访问保护(预告)

某些页面(如个人中心、购物车)必须登录才能访问。Django 提供了login_required装饰器,后续我们会这样使用:

from django.contrib.auth.decoratorsimportlogin_required @login_required(login_url='users:login')def personal_center(request):...

当未登录用户访问被保护页面时,系统会自动跳转到登录页,并带上?next=/原路径参数。这正是我们在登录视图中已经支持的next跳转机制,登录后自动返回原页面。


十一、总结与下集预告

本篇完成清单

  • 自定义认证后端:支持手机号/邮箱/用户名三种方式登录

  • 登录视图:集成"记住我"功能和next智能跳转

  • 登出功能:一行代码清除 session

  • 导航栏动态切换:根据登录状态显示不同菜单

  • 完整测试:覆盖登录、登出、错误提示等全部流程

身份认证的基础已经打牢。从下一篇开始,我们将进入用户体系的深化部分。

下集预告

第 8 篇:个人中心页面

  • 用户信息展示

  • 修改密码

  • 更换手机号/邮箱

让用户真正拥有自己的"小窝"。


📌想了解更多?搜索其它平台「IT策士」,一起升级 IT 思维!


http://www.cnnetsun.cn/news/2500954.html

相关文章:

  • 鸿蒙生鲜电商页面构建:商品网格与配送档期模块详解
  • 2026爆火!5款AI论文软件亲测,打破思路枯竭,初稿半天搞定
  • 2026 免费在线去水印工具怎么选?详细优缺点对比与实用推荐指南
  • Web 安全入门实战教程|Web 基础精讲(第二篇)
  • 2026降AI工具怎么选?4款主流工具实测,轻松把AI率压到20%内
  • SeekStorm入门指南:5分钟构建你的第一个高性能搜索引擎
  • weather_landscape性能优化技巧:提升图像生成速度和资源利用效率
  • Bandcamp音乐下载神器:高效获取高品质独立音乐的完整指南
  • 非正交相位成像下的血细胞相位恢复及三维形态重建技术【附模型】
  • 如何快速安装和配置GNOME Shell系统监视器扩展
  • 员工排班场景实测:企业级Agent如何重构企业级AI工具优化能力?
  • Flux1-dev完整教程:24GB以下显存用户的终极AI解决方案
  • ChatGPT-Web-Midjourney-Proxy 终极备份策略:数据安全与灾难恢复完全指南
  • 知识竞赛大屏计分方案:让比分一目了然
  • EditorConfig-Sublime高级技巧:Git集成与多项目配置管理终极指南
  • minecraft-ondemand故障排查指南:解决AWS无服务器我的世界服务器常见问题
  • 2026 最新完整版网安学习图谱 零基础到实战大神
  • 入门必学 Web 安全教程 从零吃透 Web 基础
  • Orbit开源贡献指南:如何参与这个前沿记忆增强研究项目
  • Aspia协议分析:深入了解自定义通信协议的实现细节
  • AI输出不可靠、总“说谎”?四步解决模型幻觉问题
  • 文档下载终极指南:kill-doc如何一键获取全网免费文档
  • 14402黄大年茶思屋144期第二题基于用户行为与内存冷热管理建模与优化问题
  • claude code、codex双AI协同高水平论文撰写与质量校准:数据分析→论文初稿→交叉审稿全流程
  • Flux1-dev 轻量级AI推理模型:为有限显存环境打造的高效解决方案
  • 2026年腾讯云OpenClaw/Hermes Agent配置Token Plan新手必看指南
  • 《Sysinternals实战指南》ListDLLs Handle 学习笔记(8.11):谁注入了 DLL?谁占着文件不放?一篇教你全搞定
  • 【2026必藏】6款智能降AIGC网站大曝光,一键秒降AI率至安全区!
  • 工业AI模型全生命周期管理:AI模型养成记
  • 【荷兰语语音生成黄金标准】:基于176小时母语者听感测试的ElevenLabs参数调优白皮书