Python进阶5:Django4-用户登录和注销的业务逻辑
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Python进阶5:Django4-用户登录和注销的业务逻辑,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含14976字,纯文字阅读大概需要22分钟。
内容图文
![Python进阶5:Django4-用户登录和注销的业务逻辑](/upload/InfoBanner/zyjiaocheng/599/cec0188a5a524e47a00d1a49f7a8a8ae.jpg)
文章目录
1. 路由与视图函数框架搭建
URL | 视图views | 模板 | 功能 |
---|---|---|---|
/index/ | login.views.index | index.html | 首页 |
/login/ | login.views.login | login.html | 登录页面 |
/register/ | login.views.register | register.html | 注册界面 |
/logout/ | login.views.logout | 无需返回页面 | 登出界面 |
访问策略:
- 未登录人员,不论是访问index还是login和logout,全部跳转到login界面
- 已登录人员,访问login会自动跳转到index页面
- 已登录人员,不允许直接访问register页面,需先logout
- 登出后,自动跳转到login界面
1.1 路由配置
- 主路由配置文件:
# loginRegister/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('login.urls')) # 添加的行, 如果没有前缀,访问子路由配置文件
]
- 子路由配置文件(login子应用的)
# login/urls.py(新建的文件)
from django.urls import path, include
from login import views
urlpatterns = [
path('index/', views.index, name='index'),
path('login/', views.login, name='login'),
path('register/', views.register, name='register'),
path('logout/', views.logout, name='logout'),
]
1.2 视图函数的配置
from django.shortcuts import render
# Create your views here.
from datetime import datetime, timedelta
from django.core.mail import send_mail
from django.shortcuts import render, redirect
# Create your views here.
from login.forms import LoginForm, RegisterForm
from login.models import SiteUser, ConfirmString
from login.utils import hash_code, make_confirm_string, send_email
from loginRegister import settings
def index(request):
if request.session.get('is_login'):
return render(request, 'login/index.html')
return redirect('/login/')
def login(request):
if request.method == 'POST':
login_form = LoginForm(request.POST)
if login_form.is_valid():
username = login_form.cleaned_data.get('username')
password = login_form.cleaned_data.get('password')
user = SiteUser.objects.filter(name=username, password=hash_code(password)).first()
if user:
if not user.has_confirmed:
message = '该用户还未经过邮件确认!'
return render(request, 'login/login.html', locals())
request.session['is_login'] = True
request.session['user_id'] = user.id
request.session['username'] = user.name
return redirect('/index/')
else:
message = "用户名或者密码错误"
return render(request, 'login/login.html', locals())
else:
message = "填写的登录信息不合法"
return render(request, 'login/login.html', locals())
login_form = LoginForm()
return render(request, 'login/login.html', locals())
def register(request):
# 如果用户已经登录,则不能注册跳转到首页。
if request.session.get('is_login', None):
return redirect('/index/')
# 如果是POST请求
if request.method == 'POST':
print(request.POST)
register_form = RegisterForm(request.POST)
message = "请检查填写的内容!"
# 先验证提交的数据是否通过
if register_form.is_valid():
# 清洗数据
username = register_form.cleaned_data.get('username')
password1 = register_form.cleaned_data.get('password1')
password2 = register_form.cleaned_data.get('password2')
email = register_form.cleaned_data.get('email')
# 接下来判断用户名和邮箱是否已经被注册
same_name_user = SiteUser.objects.filter(name=username)
print(same_name_user)
if same_name_user:
message = '用户名已经存在'
return render(request, 'login/register.html', locals())
same_email_user = SiteUser.objects.filter(email=email)
if same_email_user:
message = '该邮箱已经被注册了!'
return render(request, 'login/register.html', locals())
try:
# 将注册的信息存储到数据库,跳转到登录界面
new_user = SiteUser(name=username, password=hash_code(password1), email=email)
new_user.save()
# 生成确认码并发送确认邮件
code = make_confirm_string(new_user)
print('code:', code)
send_email(email, code)
message = '请前往邮箱进行确认!'
except Exception:
new_user.delete()
message = '发送邮件失败!'
return render(request, 'login/register.html', locals())
else:
return redirect('/login/')
# 如果是GET请求,返回用户注册的html页面。
register_form = RegisterForm()
return render(request, 'login/register.html', locals())
def logout(request):
# 如果状态不是登录状态,则无法登出。
if request.session.get('is_login'):
request.session.flush() # 清空session信息
return redirect('/login/')
def user_confirm(request):
code = request.GET.get('code', None)
message = ''
try:
confirm = ConfirmString.objects.get(code=code)
except:
message = '无效的确认请求!'
return render(request, 'login/confirm.html', locals())
create_time = confirm.create_time
now = datetime.now()
print(now, create_time, create_time + timedelta(settings.CONFIRM_DAYS))
if now > create_time + timedelta(settings.CONFIRM_DAYS):
confirm.user.delete()
message = '您的邮件已经过期!请重新注册!'
else:
confirm.user.is_confirmed = True
confirm.user.save()
confirm.delete()
message = '感谢确认,请使用账户登录!'
return render(request, 'login/confirm.html', locals())
1.3 模板template的配置
- templates/login/index.html(新建)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body> <h1>这是首页的模拟界面</h1>
</body>
</html>
- templates/login/login.html(新建)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
</head>
<body>
<h1>用户登录</h1>
<form>
用户名: <input type="text" placeholder="username"><br/>
密码: <input type="password" placeholder="password"><br/>
<input type="submit" value="登录">
</form>
</body>
</html>
- templates/login/register.html(新建)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册界面</title>
</head>
<body>
<h1>用户注册</h1>
<form>
用户名: <input type="text" placeholder="username"><br/>
电子邮箱: <input type="email" placeholder="email"><br/>
密码: <input type="password" placeholder="password"><br/>
确认密码: <input type="password" placeholder="password"><br/>
<input type="submit" value="注册">
</form>
</body>
</html>
测试是否成功
浏览器访问,检测是否成功
- 访问网址: http://127.0.0.1:9999/index/
- 访问网址: http://127.0.0.1:9999/login/
- 访问网址: http://127.0.0.1:9999/register/
2. 前端界面设计与优化(使用Bootstrap开发)
在颜值即正义的年代,但没有CSS和JS,样子真的令人无法接受。
然而,大多数使用Django的人都不具备多高的前端水平,通常也没有专业的前端工程师配合,自己写的CSS和JS却又往往惨不忍睹。怎么办?没关系,我们有现成的开源前端CSS框架!Bootstrap4就是最好的CSS框架之一!了解更多
Bootstrap核心汇总:
2.1 login.html
<!doctype html>
<html lang="zh-CN">
<head>
<!-- 必须的 meta 标签 -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap 的 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
<title>用户登录</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm">
</div>
<div class="col-sm-3 col-sm-3">
<h3 style="text-align:center">用户登录</h3>
<form>
<div class="form-group">
<label>用户名</label>
<input type="test" class="form-control">
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" >
<small id="emailHelp" class="form-text text-muted">密码必须是字母,数字或特殊符号组成.</small>
</div>
<ins href="/register/" class="text-success"><ins>新用户注册</ins></a>
<button type="submit" class="btn btn-primary float-right">登录</button>
</form>
</div>
<div class="col-sm">
</div>
</div>
</div>
<!-- JavaScript 文件是可选的。从以下两种建议中选择一个即可! -->
<!-- 选项 1:jQuery 和 Bootstrap 集成包(集成了 Popper) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-LCPyFKQyML7mqtS+4XytolfqyqSlcbB3bvDuH9vX2sdQMxRonb/M3b9EmhCNNNrV" crossorigin="anonymous"></script>
<!-- 选项 2:Popper 和 Bootstrap 的 JS 插件各自独立 -->
<!--
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js" integrity="sha384-gRC4eoaRyQ8xv2X6Mnf+eOIrtON3wId3dAkwO0HQX26OrFBoLpjX/XWOJacSiZhL" crossorigin="anonymous"></script>
-->
</body>
</html>
网页效果:
2.2 register.html
<!doctype html>
<html lang="zh-CN">
<head>
<!-- 必须的 meta 标签 -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap 的 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
<title>注册界面</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm">
</div>
<div class="col-sm-3 col-sm-3">
<h3 style="text-align:center">用户注册</h3>
<form>
<div class="form-group">
<label>用户名</label>
<input type="test" class="form-control">
</div>
<div class="form-group">
<label>电子邮箱</label>
<input type="email" class="form-control">
</div>
<div class="form-group">
<label>密码</label>
<input type="password" class="form-control" >
<small id="emailHelp" class="form-text text-muted">密码必须是字母,数字或特殊符号组成.</small>
</div>
<div class="form-group">
<label>确认密码</label>
<input type="password" class="form-control" >
<small id="emailHelp" class="form-text text-muted">密码必须是字母,数字或特殊符号组成.</small>
</div>
<ins href="/login/" class="text-success"><ins>用户登录</ins></a>
<button type="submit" class="btn btn-primary float-right">注册</button>
</form>
</div>
<div class="col-sm">
</div>
</div>
</div>
<!-- JavaScript 文件是可选的。从以下两种建议中选择一个即可! -->
<!-- 选项 1:jQuery 和 Bootstrap 集成包(集成了 Popper) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-LCPyFKQyML7mqtS+4XytolfqyqSlcbB3bvDuH9vX2sdQMxRonb/M3b9EmhCNNNrV" crossorigin="anonymous"></script>
<!-- 选项 2:Popper 和 Bootstrap 的 JS 插件各自独立 -->
<!--
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js" integrity="sha384-gRC4eoaRyQ8xv2X6Mnf+eOIrtON3wId3dAkwO0HQX26OrFBoLpjX/XWOJacSiZhL" crossorigin="anonymous"></script>
-->
</body>
</html>
网页效果:
2.3 警告界面
<div class="alert alert-warning alert-dismissible fade show" role="alert">
<strong>登录失败!</strong>用户密码错误
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
2.4 完善登录视图函数
2.4.1 html和视图函数交互的完善
- 修改1. 有message信息则显示, 没有就不显示。
- 修改2: 提交登录信息时, 以post方法提交给/login/对应的是视图函数处理。
- 修改3: Django提供了csrf防攻击的机制, 添加该信息则可顺利访问登陆界面
- 修改4:name="username"指定表单内容存储的key值名称, eg: {“username”:“你填的用户
名”,“password”:“你填的密码” }
当用户单击登录按钮时,执行的操作是以post方法访问/login路由对应的视图函数
# templates/login/login.html
<div class="col-sm">
<h3 style="text-align: center">用户登录</h3>
# 修改1. 有message信息则显示, 没有就不显示。
{% if message %}
<div class="alert alert-warning" role="alert">
<strong>登录失败!</strong> {{ message }}
</div>
{% endif %}
# 修改2: 提交登录信息时, 以post方法提交给/login/对应的是视图函数处理。
<form action="/login/" method="post">
# 修改3: Django提供了csrf防攻击的机制, 添加该信息则可顺利访问登陆界面
{% csrf_token %}
<div class="form-group">
<label>用户名</label>
# 修改4:name="username"指定表单内容存储的key值名称, eg: {"username":"你填的用户名"}
<input type="text" class="form-control" name="username">
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" name="password">
<small class="form-text text-muted">密码必须是字母、数字或者特殊符号 组成</small>
</div>
<a href="/register/" class="text-success"> <ins>新用户注册</ins>
</a>
<button type="submit" class="btn btn-primary float-right">登录 </button>
</form>
</div>
2.4.2 视图函数的完善
# login/views.py
def login(request):
if request.method == 'POST':
username = request.POST.get('username').strip()
password = request.POST.get('password').strip()
# print(username, password)
if username and password:
user = SiteUser.objects.filter(name=username, password=password).first()
if user:
return redirect('/index/')
else:
message = "用户名或者密码错误"
return render(request, 'login/login.html', {'message':message})
else:
message = "非法的数据信息"
return render(request, 'login/login.html', {'message': message})
return render(request, 'login/login.html')
浏览器访问,检测是否成功:
- 访问网址: http://127.0.0.1:9999/login/
- 填写正确的用户名和密码/错误的用户名和密码测试是否为期待的效果。
2.5 session会话与登录的视图函数
- 登录成功, 存储登录的用户信息到session中
# login/views.py
def login(request):
if request.method == 'POST':
username = request.POST.get('username').strip()
password = request.POST.get('password').strip()
# print(username, password)
if username and password:
user = SiteUser.objects.filter(name=username, password=password).first()
if user:
# ------------核心修改的内容开始
request.session['is_login'] = True
request.session['user_id'] = user.id
request.session['username'] = user.name
# --------------核心修改的内容结束
return redirect('/index/')
else:
message = "用户名或者密码错误"
return render(request, 'login/login.html', {'message':message})
else:
message = "非法的数据信息"
return render(request, 'login/login.html', {'message': message})
return render(request, 'login/login.html')
- 登出时,清空session信息
# login/views.py
def logout(request):
# 如果状态不是登录状态,则无法登出。
if request.session.get('is_login'):
request.session.flush() # 清空session信息
return redirect('/login/')
- 在首页添加登出的超链接并测试
# templates/login/index.html
# 核心代码如下:
<h1>你好, {{ request.session.username }}, 这是首页的模拟界面</h1>
<a href="/logout/"><strong style="font-size: 20px">登出</strong></a>
- 浏览器访问,检测是否成功
访问网址: http://127.0.0.1:9999/index/
内容总结
以上是互联网集市为您收集整理的Python进阶5:Django4-用户登录和注销的业务逻辑全部内容,希望文章能够帮你解决Python进阶5:Django4-用户登录和注销的业务逻辑所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。