书接上文,我们已经对登录做了不少处理,但是还是不是很好,于是才有了今天的优化问题。
我看网上有很多人会使用form表单来去处理登录注册逻辑,但是我感觉这样使用不是很方便。但是为了接触多一点,于是也硬着头皮写来了。
先去login app中forms.py(如果没有,我们就自己新建)中写上我们需要在前端展示的字段,也就是输入信息。注意要引入《from django import forms》。可以先不用管captchafield是什么意思。
from django import forms
from captcha.fields import CaptchaField
class UserForm(forms.Form):
# 一个forms代表一个input输入框
username = forms.CharField(label="用户名",max_length=128,widget=forms.TextInput(attrs={"placeholder":"please enter username","autofocus":"","autocomplete":"off"}))
# widget=forms.PasswordInput表示设置他是密码输入框,输入进去是显示***
password = forms.CharField(label="密码", max_length=256,widget=forms.PasswordInput(attrs={"placeholder":"please enter password","autocomplete":"off"}))
capture = CaptchaField(label="验证码")
再去views.py中处理视图函数,为了与前面写的区分一下,我们这里就新建一个login1函数来表示。
def login1(request):
# 先调用表单,不然首次进入不显示
loginform = forms.UserForm()
# 如果用户已经登录,那就去首页,默认未登录态
if request.session.get('is_login',None):
return redirect('/index/')
if request.method == "POST":
# 获取表单的数据
loginform = forms.UserForm(request.POST)
message = "请确定输入框信息"
# Return True if the form has no errors, or False otherwise
if loginform.is_valid():
# 从表单中获取用户输入的用户名和密码
username = loginform.cleaned_data.get('username')
password = loginform.cleaned_data.get('password')
try:
# 从数据库获取用户信息,注册之后就会有
user = User.objects.get(name=username)
except:
message = "用户数据不存在"
# 没有获取到数据,那就去登录页,locals()等效于{"message":message,"loginform":loginform}
return render(request, "login/login.html", locals())
# if user.password == password:
if user.password == MD5code(password):
# 登录成功,给他加上session等一些必须的字段
request.session['is_login'] = True
request.session['user_id'] = user.id
request.session['user_name'] = user.name
# return redirect("/index/")
return render(request, "login/index.html", locals())
else:
message = "密码不正确"
return render(request,"login/login.html",locals())
else:
return render(request, "login/login.html",locals())
# get请求,没有数据获取
loginform = forms.UserForm()
return render(request, "login/login.html",locals())
接着再去处理前端,打开login.html,我们这里要更改,这样会省略很多代码。也就是将前面自己写的输入用户名,密码这两个表单用iambic代码代替即可,不要更换其它东西哦。使用这个的唯一好处就是代码少,但是坏处我认为是不少的,比如前端总是要表现的很花里胡哨,但是使用这个之后,如果要css处理,我们还需要给他套一个壳,这样难免有些麻烦。(你们可以自己给他加个div或者span去处理一下哈)当然也可以在forms.py中加上《widget=forms.PasswordInput(attrs={“placeholder”:“please enter password”,“autocomplete”:“off”})》去处理,还有一些其它的参数可以自己去网上查,因为我不太喜欢这个就没怎么处理。难过。。。
{{ loginform }}
{{ loginform.username.label_tag }}
{{ loginform.username }}
<br><br>
{{ loginform.password.label_tag }}
{{ loginform.password }}
<br><br>
好了,这就是一个小优化,但是我们可以忽略哦,因为不是人人都得forms.py去写。
现在书接正文,我们来到注册模块。
前几节我们有写urls.py和他的视图函数,我们只需要在视图函数中做一下处理即可。
# 注册页面
# 注册逻辑:从前端获取用户输入的数据,再去做其它判断,比如用户已经存在,两次密码不等,邮箱已经存在(需要明白filter和get的区别)
# 然后将和上述数据插入数据库,save保存。
def register(request):
if request.session.get('is_login',None):
return redirect('/index/')
if request.method == "POST":
username = request.POST.get('username')
password1 = request.POST.get('password1')
password2 = request.POST.get('password2')
email = request.POST.get('email')
sex = request.POST.get('sex')
message = "请确定输入框信息"
# 做输入数据的判断
if password1 != password2:
message = "两次密码不对称"
return render(request,'login/register.html',locals())
else:
same_user_name = User.objects.filter(name=username)
if same_user_name:
message = "用户已经存在"
return render(request, 'login/register.html', locals())
same_user_email = User.objects.filter(email=email)
if same_user_email:
message = "邮箱已经注册"
return render(request, 'login/register.html', locals())
new_user = User()
new_user.name = username
# new_user.password = password1
new_user.password = MD5code(password1)
new_user.email = email
new_user.sex = sex
new_user.save()
return redirect('/login/')
else:
return render(request, 'login/register.html', locals())
再去处理register.html内容,注意哦,不能什么都抄我的代码,我的只是给你看看,因为有些前端样式写的很乱,还有些不存在或者没使用到的地方。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body{
background: url("../../../static/login/images/bgc.png") no-repeat;
background-size: 100%;
}
input{
height: 25px;
width: 300px;
}
input:nth-of-type(3){
width: 280px;
}
input:last-child{
margin-left: 40px;
width: 90px;
}
select{
width: 80px;
margin-left: 230px;
}
a{
text-decoration: none ;
color: black;
}
a:hover{
color: red;
}
</style>
</head>
<body>
<h1 style="text-align: center">register! </h1>
<br><br>
<div class="registerpage">
<form action="/register/" method="post" style="text-align: center">
{% csrf_token %}
<label for="name">用户名: </label>
<input id="name" type="text" name="username" placeholder="please enter username" autofocus required autocomplete="off"/>
<br><br>
<label for="password1">密 码: </label>
<input id="password1" type="password" name="password1" placeholder="please enter password" required autocomplete="off"/>
<br><br>
<label for="password2">确认密码: </label>
<input id="password2" type="password" name="password2" placeholder="please enter password again" required autocomplete="off"/>
<br><br>
<label for="email">邮 箱:</label>
<input type="email" id="email" name="email" placeholder="please enter email" required autocomplete="off">
<br><br>
{# <div>#}
{# <label for="sex">性 别:</label>#}
{# <input type="radio" name="sex" id="nan" style="padding-left: 30px; width: 50px; margin-left: 70px">Nan#}
{# <input type="radio" name="sex" id="nv" style="width: 50px; margin-left: 60px">Nv#}
{# </div>#}
{# <br><br>#}
<div>
<label for="sex">性 别:</label>
<select name="sex" style="margin-left: 100px; width: 200px; height: 30px; border-radius: 8px">
<option value="male" selected>男</option>
<option value="female">女</option>
</select>
</div>
<br><br>
<a href="/login/">已有账号?去登录</a>
<input type="submit" value="注册">
</form>
</div>
</body>
</html>
好了,可以尝试一下能不能注册,注册成功之后会跳转到登录去哦。
不知道有没有发现,这有一句代码是这样的。我这边调用了hashlib库,来去对密码做加密处理。这样保存在数据库时候,不再是明文的密码,而是让我们看不懂的组合。这也是为什么上面登录的地方也有一块代码处理。
注册模块加入数据库
new_user.password = MD5code(password1)
登录模块对密码做判断
if user.password == MD5code(pwd):
那么怎么加密的呢?在views.py中我们使用这样一个函数,别忘了在开头要导包。
# 对密码加密操作,在登录注册时候调用
import hashlib
def MD5code(str):
# 创建md5对象
m = hashlib.md5()
# 将明文密码编码处理先,否则异常
se = str.encode(encoding='utf-8')
# 给对象加密,获取加密后的字符串密码
m.update(se)
str_md5 = m.hexdigest()
print(str_md5)
return str_md5
最后一点,不知道有没有发现还有这样两端代码,这是因为我们采用了django自带的session模块,登录以后就将数据存在session中。当然我们除了加下面那些字段,还可以加其它的东西哦。
if request.session.get('is_login',None):
return redirect('/index/')
request.session['is_login'] = True
request.session['user_id'] = user.id
request.session['user_name'] = user.name
只是在退出登录时候,需要清除session
def get(self,request):
# 如果没有登录,那就去登录页
if not request.session.get('is_login',None):
return redirect('/login/')
# 退出操作的清除session内容,不推荐用del删除
print(request.session)
request.session.flush()
return redirect('/login/')
好了,整体大部分就是这样了,我也知道写的好乱,我将就着以后就这样看吧。再会。