在实际Python web开发过程中,我们经常会碰到这样的应用场景。当用户试图访问某个页面或评论某个页面时,我们会要求其先登录,然后在用户在登录后自动跳转到用户试图访问的页面。
1. settings.py配置
# 配置登录的url
LOGIN_URL = "/login/"
2. views.py代码
from django.shortcuts import render, redirect, reverse
from django.views.generic.base import View
from django.http import HttpResponse
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from .forms import LoginForm
@method_decorator(login_required, name="dispatch")
class IndexView(View):
def get(self, request):
return render(request, "index.html")
class LoginView(View):
def get(self, request):
if request.user.is_authenticated:
return redirect(reverse("app01:index"))
loginform = LoginForm()
next = request.GET.get("next", "")
return render(request, "login.html", {"loginform": loginform, "next": next})
def post(self, request):
loginform = LoginForm(request.POST)
next = request.POST.get("next", "")
if loginform.is_valid():
# 如果校验通过才会查询数据库校验用户名和密码是否匹配,如果校验都不通过,也就省去了查询数据库了
data = loginform.cleaned_data
# 判定用户名密码是否正确
user = authenticate(**data)
# 登录
if user is not None and user.is_active:
login(request, user)
# 登录成功,跳转到之前访问的页面
# return redirect()
if next == "":
return HttpResponse("登录成功")
else:
# return redirect(next)
return redirect(next)
else:
return render(request, "login.html", {"loginform": loginform, "err_msg": "用户名或密码错误",
"next": next})
else:
for key, val in loginform.errors.items():
print(key, val[0])
return render(request, "login.html", {"loginform": loginform, "err": loginform.errors,
"next": next})
3. login.html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.errorlist{
font-size: 10px;
color: red;
}
</style>
</head>
<body>
<form action="{% url 'app01:login' %}" method="post" novalidate>
{% csrf_token %}
{# {
{ loginform.as_p }}#}
{# 用户名的设置 #}
{
{ loginform.username.label_tag }}
{
{ loginform.username }} <br>
{
{ loginform.username.errors }}
{# 密码的设置 #}
{
{ loginform.password.label_tag }}
{
{ loginform.password }} <br>
{
{ loginform.password.errors }}
{# 用户名或密码错误 #}
<span class="errorlist">{
{ err_msg }}</span>
{# 隐藏域 显示next值#}
<input type="hidden" name="next" value="{
{ next }}">
<br>
<input type="submit" value="登录">
</form>
</body>
</html>
4. index.html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
首页
</body>
</html>
由于我们登录时对用户名和密码做了一些校验,forms.py代码如下:
import re
from django import forms
class LoginForm(forms.Form):
username = forms.CharField( # 用户名
label="用户名",
max_length=10,
min_length=2,
required=True,
error_messages={
"max_length": "用户名最大长度为10",
"min_length": "用户名最小长度为2",
"required": "用户名不能为空"
}
)
password = forms.CharField( # 密码
label="密码",
max_length=20,
min_length=6,
required=True,
error_messages={
"max_length": "密码最大长度为20",
"min_length": "密码最小长度为6",
"required": "密码不能为空"
},
# 将input类型设置成password类型
widget=forms.widgets.PasswordInput()
)
def clean_password(self):
password = self.cleaned_data.get("password")
print(password)
ret = re.match(r"^\d+$", password)
print(ret)
if ret:
raise forms.ValidationError("密码不能是纯数字")
return password