前言
在django中,django帮我们封装好了登录注册以及注销的函数,在下面的代码案例中,我们将使用django定义好的注册登录注销函数去实现用户的登录验证,用户登录,以及用户注销等操作,以及定义login_rqueired装饰器,去装饰我们定义的函数,实现登录才能处理对应的业务逻辑。以及如何通过表单校验页面中的参数。
1.创建用户user模块
在Django项目中,按照功能模块可以创建不同的应用app。针对用户管理模块可以创建users应用。
1)创建应用命令:python manage.py startapp users。
2)在settings.py中INSTALLED_APPS中添加应用users。
3)在settings.py中添加LOGIN_URL= '/user/login/',该参数表示,如果用户没有登录则跳转的地址。具体如何判断用户是否登录,请看步骤3路由的配置。
2.定义模板:在templates文件夹中先定义父模板base.html、login.html、register.html、index.html。
1.定义父模板base.html:
{% block title %}
{% endblock %}
{% block extCss %}
{% endblock %}
{% block extJs %}
{% endblock %}
{% block content %}
{% endblock %}
2)、定义子模板注册页register.html:
{% extends 'base.html' %}
{% block title %}
注册
{% endblock %}
{% block content %}
3)、定义子模板登录页面login.html
{% extends 'base.html' %}
{% block title %}
登录
{% endblock %}
{% block content %}
{% endblock %}
4)、定义首页index.html
{% extends 'base.html' %}
{% block title %}
首页
{% endblock %}
{% block content %}
我是首页,我需要登录后才能访问
{% endblock %}
3-定义路由-在urlspy中定义路由匹配规则使用login_required装饰器如果用户没有登录则不让访问对应的视图函数而是跳转到登录地址在1中设置的login_url地址)3. 定义路由: 在urls.py中定义路由匹配规则。使用login_required装饰器,如果用户没有登录则不让访问对应的视图函数,而是跳转到登录地址(在1中设置的LOGIN_URL地址)。
from django.conf.urls import url
from django.contrib.auth.decorators import login_required
# 在hello/hello/urls.py配置如下路由
url(r'user/', include('users.urls', namespace='user')),
# 在hello/users/urls.py配置如下路由
# 定义注册URL
path(r'^register/', views.register, name='register'),
# 定义登录URL
path(r'^login/', views.login, name=login),
# 定义注销URL
path(r'^logout/', login_required(views.logout), name=logout),
# 首页
url(r'^index/', login_required(views.index), name='index'),
4. 新建forms.py文件,并定义UserRegisterForm表单类和UserLoginForm表单类。在表单类中定义校验的字段是否为必填项即required参数的设置,以及长度的限制即max_length、min_length,以及错误信息的自定义error_messages。通过重构clean()方法实现用户名的检测等功能。
from django import forms
from django.contrib.auth.models import User
class UserRegisterForm(forms.Form):
"""
校验注册信息
"""
username = forms.CharField(required=True, max_length=5, min_length=2,
error_messages={
'required': '用户名必填',
'max_length': '用户名不能超过5个字符',
'min_length': '用户名不能少于2个字符'
})
password = forms.CharField(required=True, min_length=6,
error_messages={
'required': '密码必填',
'min_length': '密码不能少于6个字符'
})
password2 = forms.CharField(required=True, min_length=6,
error_messages={
'required': '确认密码必填',
'min_length': '确认密码不能少于6个字符'
})
def clean(self):
# 校验用户名是否已经注册过
user = User.objects.filter(username=self.cleaned_data.get('username'))
if user:
# 如果已经注册过
raise forms.ValidationError({'username': '用户名已存在,请直接登录'})
# 校验密码和确认密码是否相同
if self.cleaned_data.get('password') != self.cleaned_data.get('password2'):
raise forms.ValidationError({'password': '两次密码不一致'})
return self.cleaned_data
class UserLoginForm(forms.Form):
"""
校验登录信息
"""
username = forms.CharField(required=True, max_length=5, min_length=2,
error_messages={
'required': '用户名必填',
'max_length': '用户名不能超过5个字符',
'min_length': '用户名不能少于2个字符'
})
password = forms.CharField(required=True, min_length=6,
error_messages={
'required': '密码必填',
'min_length': '密码不能少于6个字符'
})
def clean(self):
# 校验用户名是否注册
user = User.objects.filter(username=self.cleaned_data['username'])
if not user:
raise forms.ValidationError({'username': '请先注册再来登录'})
return self.cleaned_data
5. 定义视图函数,在视图函数中分别使用表单校验POST提交的参数,表单可以校验字段是否填写,是否字段超过了最大长度或者最短长度的限制,或者重定义clean()方法来校验用户是否注册、密码和确认密码是否相同等信息。如果表单校验成功,则is_valid()返回True。在登录方法中,当UserLoginForm验证参数成功后,使用auth.authenticate(username = form.cleaned_data['username'],password = form.cleaned_data['password'])可以获取到当前用户对象,如果获取到当前用户对象可以使用auth.login(request, user)进行注册。在用户登录后可以使用auth.logout(request)进行注销用户的登录状态。
from django.contrib import auth
from django.contrib.auth.models import User
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse
from users.forms import UserRegisterForm, UserLoginForm
def register(request):
"""
定义注册方法
"""
if request.method == 'GET':
return render(request, 'register.html')
if request.method == 'POST':
# 校验页面中传递的参数,是否填写完整
form = UserRegisterForm(request.POST)
# is_valid():判断表单是否验证通过
if form.is_valid():
# 获取校验后的用户名和密码
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
# 创建普通用户create_user,创建超级管理员用户create_superuser
User.objects.create_user(username=username, password=password)
# 实现跳转
return HttpResponseRedirect(reverse('user:login'))
else:
return render(request, 'register.html', {'form': form})
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
if request.method == 'POST':
# 表单验证,用户名和密码是否填写,校验用户名是否注册
form = UserLoginForm(request.POST)
if form.is_valid():
# 校验用户名和密码,判断返回的对象是否为空,如果不为空,则为user对象
user = auth.authenticate(username = form.cleaned_data['username'],
password = form.cleaned_data['password'])
if user:
# 用户名和密码是正确的,则登录
auth.login(request, user)
return HttpResponseRedirect(reverse('user:index'))
else:
# 密码不正确
return render(request, 'login.html', {'error': '密码错误'})
else:
return render(request, 'login.html', {'form': form})
def index(request):
if request.method == 'GET':
return render(request, 'index.html')
def logout(request):
if request.method == 'GET':
# 注销
auth.logout(request)
return HttpResponseRedirect(reverse('user:login'))
注意:用户的登录状态是保存在request.user中。如果没有登录,则request.user为AnonymousUser对象。如果用户登录后,则request.user为User对象。