Cookie和Session
我们继续来完成上一章节中的项目,实现“用户登录”的功能,并限制只有登录的用户才能投票。
用户登录的准备工作
我们先为实现用户登录做一些准备工作。
-
创建用户模型。之前我们讲解过如果通过Django的ORM实现从二维表到模型的转换(反向工程),这次我们尝试把模型变成二维表(正向工程)。
class User(models.Model): """用户""" no = models.AutoField(primary_key=True, verbose_name='编号') username = models.CharField(max_length=20, unique=True, verbose_name='用户名') password = models.CharField(max_length=32, verbose_name='密码') tel = models.CharField(max_length=20, verbose_name='手机号') reg_date = models.DateTimeField(auto_now_add=True, verbose_name='注册时间') last_visit = models.DateTimeField(null=True, verbose_name='最后登录时间') class Meta: db_table = 'tb_user' verbose_name = '用户' verbose_name_plural = '用户'
-
使用下面的命令生成迁移文件并执行迁移,将
User
模型直接变成关系型数据库中的二维表tb_user
。python manage.py makemigrations polls python manage.py migrate polls
-
用下面的SQL语句直接插入两条测试数据,通常不能将用户的密码直接保存在数据库中,因此我们将用户密码处理成对应的MD5摘要。MD5消息摘要算法是一种被广泛使用的密码哈希函数(散列函数),可以产生出一个128位(比特)的哈希值(散列值),用于确保信息传输完整一致。在使用哈希值时,通常会将哈希值表示为16进制字符串,因此128位的MD5摘要通常表示为32个十六进制符号。
insert into `tb_user` (`username`, `password`, `tel`, `reg_date`) values ('wangdachui', '1c63129ae9db9c60c3e8aa94d3e00495', '13122334455', now()), ('hellokitty', 'c6f8cf68e5f68b0aa4680e089ee4742c', '13890006789', now());
说明:上面创建的两个用户
wangdachui
和hellokitty
密码分别是1qaz2wsx
和Abc123!!
。 -
我们在应用下增加一个名为
utils.py
的模块用来保存需要使用的工具函数。Python标准库中的hashlib
模块封装了常用的哈希算法,包括:MD5、SHA1、SHA256等。下面是使用hashlib
中的md5
类将字符串处理成MD5摘要的函数如下所示。import hashlib def gen_md5_digest(content): return hashlib.md5(content.encode()).hexdigest()
-
编写用户登录的视图函数和模板页。
添加渲染登录页面的视图函数:
def login(request: HttpRequest) -> HttpResponse: hint = '' return render(request, 'login.html', {'hint': hint})
增加
login.html
模板页:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户登录</title> <style> #container { width: 520px; margin: 10px auto; } .input { margin: 20px 0; width: 460px; height: 40px; } .input>label { display: inline-block; width: 140px; text-align: right; } .input>img { width: 150px; vertical-align: middle; } input[name=captcha] { vertical-align: middle; } form+div { margin-top: 20px; } form+div>a { text-decoration: none; color: darkcyan; font-size: 1.2em; } .button { width: 500px; text-align: center; margin-top: 20px; } .hint { color: red; font-size: 12px; } </style> </head> <body> <div id="container"> <h1>用户登录</h1> <hr> <p class="hint">{ { hint }}</p> <form action="/login/" method="post"> {% csrf_token %} <fieldset> <legend>用户信息</legend> <div class="input"> <label>用户名:</label> <input type="text" name="username"> </div> <div class="input"> <label>密码:</label> <input type="password" name="password"> </div> <div class="input"> <label>验证码:</label> <input type="text" name="captcha"> <img id="code" src="/captcha/" alt="" width="150" height="40"> </div> </fieldset> <div class="button"> <input type="submit" value="登录"> <input type="reset" value="重置"> </div> </form> <div> <a hre