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

Django 从 0 到 1 打造完整电商平台:登录与登出功能实现 作者IT策士10余年一线大厂经验专注 IT 思维、架构、职场进阶。持续发布最新文章助你少走弯路。前言上一篇我们完成了用户注册功能数据库里已经积累了一批注册用户。但一个完整的身份认证体系光有注册是不够的——用户还需要能够登录和登出。今天这篇文章我们将基于 Django 内置的认证系统django.contrib.auth通过自定义认证后端实现多方式登录手机号/邮箱/用户名同时集成记住我、登录后跳转、导航栏状态切换等实用功能。跟着我的步骤半小时内让你的项目真正认人。一、需求分析我们要实现的登录功能清单功能点说明多方式登录支持手机号、邮箱、用户名任一方式登录错误提示密码错误或用户不存在时给出明确提示记住我支持延长 session 有效期导航栏切换登录后显示欢迎XXX及下拉菜单智能跳转登录后返回之前想访问的页面否则回首页安全登出清除 session回到首页二、自定义认证后端2.1 为什么要自定义Django 默认的认证后端只能通过username和password登录。但我们的注册逻辑允许用户用手机号或邮箱注册username字段存储的可能是手机号或邮箱前缀这会导致用户记不住自己的用户名。解决方案自定义认证后端让系统同时匹配手机号、邮箱和用户名。2.2 实现代码在apps/users/目录下创建backends.pyfrom django.contrib.auth.backendsimportModelBackend from django.db.modelsimportQ from .modelsimportUser class MultiFieldAuthBackend(ModelBackend): 支持手机号 / 邮箱 / 用户名 登录的自定义认证后端 def authenticate(self, request,usernameNone,passwordNone, **kwargs): try:# 使用 Q 对象进行 OR 查询同时匹配三个字段userUser.objects.get(Q(usernameusername)|Q(emailusername)|Q(phoneusername))except User.DoesNotExist:returnNone# 校验密码Django 自动处理密码哈希比对ifuser.check_password(password):returnuserreturnNone2.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): usernameforms.CharField(label账号,widgetforms.TextInput(attrs{class:form-control,placeholder:手机号 / 邮箱 / 用户名}))passwordforms.CharField(label密码,widgetforms.PasswordInput(attrs{class:form-control,placeholder:请输入密码}))rememberforms.BooleanField(label记住我,requiredFalse,widgetforms.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.methodPOST:formLoginForm(request.POST)ifform.is_valid(): usernameform.cleaned_data[username]passwordform.cleaned_data[password]rememberform.cleaned_data.get(remember)# 调用自定义后端进行认证userauthenticate(request,usernameusername,passwordpassword)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_urlrequest.GET.get(next,home)messages.success(request, f欢迎回来{user.username})returnredirect(next_url)else: messages.error(request,该账号已被禁用请联系管理员。)else: messages.error(request,账号或密码错误请重试。)else: formLoginForm()returnrender(request,users/login.html,{form:form})核心要点解析要点说明request.user.is_authenticated检查用户是否已登录避免重复登录authenticate()自动调用我们自定义的MultiFieldAuthBackendlogin(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,nameregister), path(send_sms/, views.send_sms_code,namesend_sms), path(activate/int:user_id/str:token/, views.activate_email,nameactivate_email), path(login/, views.user_login,namelogin), path(logout/, views.user_logout,namelogout),]七、登录页面模板创建apps/users/templates/users/login.html{% extendsbase.html%}{% block title %}用户登录{% endblock %}{% block content %}divclassrow justify-content-centerdivclasscol-md-6 col-lg-5divclasscard shadow-smdivclasscard-body p-4h3classtext-center mb-4 用户登录/h3formmethodpostnovalidate{% csrf_token %}!-- 全局错误提示 --{%ifform.non_field_errors %}divclassalert alert-danger{{form.non_field_errors.0}}/div{% endif %}!-- 账号输入 --divclassmb-3labelclassform-label{{form.username.label}}/label{{form.username}}{%ifform.username.errors %}divclasstext-danger small{{form.username.errors.0}}/div{% endif %}/div!-- 密码输入 --divclassmb-3labelclassform-label{{form.password.label}}/label{{form.password}}{%ifform.password.errors %}divclasstext-danger small{{form.password.errors.0}}/div{% endif %}/div!-- 记住我 --divclassmb-3 form-check{{form.remember}}labelclassform-check-labelfor{{ form.remember.id_for_label }}{{form.remember.label}}/label/divbuttontypesubmitclassbtn btn-primary w-100登录/button/formpclasstext-center mt-3还没有账号ahref{% url users:register %}立即注册/a/p/div/div/div/div{% endblock %}八、更新导航栏动态切换打开templates/base.html替换导航栏的用户相关部分ulclassnavbar-nav ms-autoliclassnav-itemaclassnav-linkhref{% url home %}首页/a/liliclassnav-itemaclassnav-linkhref#商品/a/liliclassnav-itemaclassnav-linkhref#购物车/a/li{%ifuser.is_authenticated %}!-- 已登录显示用户下拉菜单 --liclassnav-item dropdownaclassnav-link dropdown-togglehref#rolebutton>dropdown{{user.username}}/aulclassdropdown-menu dropdown-menu-endliaclassdropdown-itemhref#个人中心/a/liliaclassdropdown-itemhref#我的订单/a/lilihrclassdropdown-divider/liliaclassdropdown-itemhref{% url admin:index %}后台管理/a/liliaclassdropdown-itemhref{% url users:logout %}退出登录/a/li/ul/li{%else%}!-- 未登录显示登录/注册入口 --liclassnav-itemaclassnav-linkhref{% url users:login %}登录/a/liliclassnav-itemaclassnav-linkhref{% url users:register %}注册/a/li{% endif %}/ul效果未登录时显示登录和注册登录后显示用户名下拉菜单包含个人中心、订单、后台管理、退出登录等入口。九、完整流程测试启动开发服务器python manage.py runserver9.1 手机号登录测试访问http://127.0.0.1:8000/users/login/输入手机号13800138000上一篇注册的手机号和密码勾选记住我点击登录预期结果终端输出302重定向状态码浏览器跳转到首页导航栏显示 13800138000下拉菜单页面顶部显示绿色消息“欢迎回来13800138000”9.2 邮箱登录测试点击导航栏退出登录确认看到成功提示重新进入登录页输入邮箱testexample.com和密码点击登录预期结果同样登录成功验证自定义后端对邮箱的匹配支持。9.3 错误情况测试输入错误的密码页面应显示红色提示账号或密码错误请重试。终端返回200状态码表示停留在登录页并展示错误信息。9.4 登出流程测试点击退出登录终端输出302重定向回到首页导航栏恢复为登录和注册页面显示绿色消息“您已成功退出登录。”十、未登录访问保护预告某些页面如个人中心、购物车必须登录才能访问。Django 提供了login_required装饰器后续我们会这样使用from django.contrib.auth.decoratorsimportlogin_required login_required(login_urlusers:login)def personal_center(request):...当未登录用户访问被保护页面时系统会自动跳转到登录页并带上?next/原路径参数。这正是我们在登录视图中已经支持的next跳转机制登录后自动返回原页面。十一、总结与下集预告本篇完成清单✅自定义认证后端支持手机号/邮箱/用户名三种方式登录✅登录视图集成记住我功能和next智能跳转✅登出功能一行代码清除 session✅导航栏动态切换根据登录状态显示不同菜单✅完整测试覆盖登录、登出、错误提示等全部流程身份认证的基础已经打牢。从下一篇开始我们将进入用户体系的深化部分。下集预告第 8 篇个人中心页面用户信息展示修改密码更换手机号/邮箱让用户真正拥有自己的小窝。想了解更多搜索其它平台「IT策士」一起升级 IT 思维