Python Web 菜谱项目再次前进一步,从应用层了解内置用户认证系统
橡皮擦,一个逗趣的互联网高级网虫。新的系列,让我们一起进入 Django 世界。
九、Django 用户认证与鉴权,注册登录逻辑实现,注销功能
9.1 Django 用户认证
之前的博客中已经对 Django 中用户身份认证系统有过初步了解,在这套用户身份认证系统中可以处理用户账户,用户组,用户权限,Cookie 想干问题,主要解决了 Web 系统中两个问题,分别是认证、鉴权。
认证解决的是否可以登录问题,鉴权解决用户登录之后可以做什么的问题。
在 Django 中内置了一个 User 模型,字段如下:
username
:用户名,150 字符以内;firstname
:名字字段,30 字符以内,国内不常用;lastname
:姓字段,150 字符以内,国内不常用;email
:邮箱字段;password
:密码字段;groups
:用户组字段;is_staff
:是否是管理员,布尔类型;is_active
:用户是否可用,布尔类型;is_superuser
:超级管理员字段;last_login
:用户最后登录时间;date_joined
:用户账号创建时间。
9.1.1 创建用户
在 Django 的用户系统中,因为涉及密码管理,不能直接通过 User 类的构造函数创建 User 对象并调用 save 方法创建用户。
一般使用 User 模型的 Manage 提供的 create_user
方法,传入参数实现对用户的创建。
# 第一个参数是用户名,第二个参数是邮箱,第三个参数是密码
user = User.objects.create_user("xiangpica","xxxxxxxxx@88.com","admin_123")
修改密码,使用下述方法。
user = User.objects.get(username="xiangpica")
user.set_password("C@xiang")
user.save()
这个是普通用户的创建方式,如果希望创建一个超级用户,使用 createsuperuser
命令即可,可参考下述步骤。
> python manage.py createsuperuser
Username (leave blank to use 'administrator'): xiang
Email address: w@163.com
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
This password is too common.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
9.2 注册登录逻辑实现
接下来就要实现上文未完成的逻辑部分想干代码了,这里需要补充的知识也比较抽象,第一个就是在一个网站中,如果用户登录成功,Django 会通过 cookie 信息记录用户的登录状态,并且可以通过 cookie 中的信息查找到 session(会话)和用户信息,依旧是先实现,再补充逻辑知识点。
9.2.1 注册用户入库
在正式注册前,先打开 sqlite3
看一下里面的数据,这里橡皮擦使用的软件是 https://sqlitebrowser.org/dl/
。直接打开项目目录的 db.sqlite3
文件即可查阅。
修改 views.py
文件中内部逻辑,修改 register.html
页面逻辑,代码如下:
views.py
# 投入记住先导入该模块
from django.contrib.auth.models import User
def register(request):
if request.user.is_authenticated:
return HttpResponseRedirect(reverse("default"))
# 用户注册状态信息
state = None
# 当用户提交注册信息
if request.method == "POST":
username = request.POST.get("username", "")
password = request.POST.get("password", "")
email = request.POST.get("email", "")
# 判断用户名是否存在
if User.objects.filter(username=username):
state = "user_exist"
else:
n_user = User.objects.create_user(username=username, password=password, email=email)
# 保存注册信息到数据库
n_user.save()
state = "success" # 表示注册成功
context = {
"active_menu": 'default',
"user": None,
"state": state
}
return render(request, "menuapp/register.html", context)
register.html
{% block content %}
<div class="container">
<h2 class="form-signup-heading">注册</h2>
<div class="well">
{% if state == "user_exist" %}
<h2 class="text-warning">用户已经被注册!</h2>
{% endif %} {% if state == "success" %}
<h2 class="text-success">注册成功!</h2>
{% endif %}
</div>
</div>
重新运行菜谱程序,注册用户,第一次成功,第二次在注册,提示用户已经被注册,此时注册界面完成最小可用功能。
查询数据库数据,发现已经入库。
9.2.2 用户登录完善
模仿注册相关实现,对登录逻辑进行补充,重点修改 views.py
文件与 login.html
文件:
login.html
{% block content %}
<div class="container">
<h2 class="form-signup-heading">登录</h2>
{% if state == "login_error" %}
<h2 class="text-warning">用户名或者密码错误!</h2>
{% endif %}
</div>
# 提前导入 auth 模块
from django.contrib import auth
# 登录视图
def login(request):
if request.user.is_authenticated:
return HttpResponseRedirect(reverse("default"))
# 登录状态信息
state = None
if request.method == "POST":
username = request.POST.get("username", "")
password = request.POST.get("password", "")
# 登录验证
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
return HttpResponseRedirect(reverse("default"))
else:
state = "login_error"
context = {
"active_menu": 'default',
"user": None,
"state": state
}
return render(request, "menuapp/login.html", context)
修改完毕之后,运行网站,结果出现如下错误,反复查询之后,在 urls.py
文件中,一个路由的名字写错了,修改如下:
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="default"),
path("register", views.register, name="register"),
path("login", views.login, name="login")
]
上述代码成功解决下述问题。
以上代码正常运行的结果是,当用户正常登录之后,会跳转到首页,重新去访问登录页面,也会跳转到首页,简单理解就是你的登录页面进不去了,除非手动删除本地 cookie。
9.3 用户注销
注销不需要有页面,但是需要完成 views.py
中的 logout
函数。
def logout(request):
# 注销登录
auth.logout(request)
return HttpResponseRedirect(reverse("default"))
修改完毕 views.py
代码之后,还要在 urls.py
中新增注销用户的路由。
urlpatterns = [
path("", views.index, name="default"),
path("register", views.register, name="register"),
path("login", views.login, name="login"),
path("logout", views.logout, name="logout")
]
访问 http://127.0.0.1:8000/logout
实现注销,同时 http://127.0.0.1:8000/login
可以再次访问。
9.4 本篇博客小节
本篇博客对菜谱系统的登录与注册页面逻辑进行了补充,实现了基于内置 User 模型的增加操作。文章难度虽然不大,但是核心知识点比较多,并且有许多位置的技术知识点被后置了,这些内容在后续都将为你展开,一起坚持学习吧。
今天是持续写作的第 127 / 200 天。
博主 ID:梦想橡皮擦,希望大家点赞、评论、收藏。
- 点赞
- 收藏
- 关注作者
评论(0)