我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统。此时我们需要实现包括用户注册、用户登录、用户认证、注销、修改密码等功能,这还真是个麻烦的事情呢。
Django作为一个完美主义者的终极框架,当然也会想到用户的这些痛点。它内置了强大的用户认证系统--auth,它默认使用 auth_user 表来存储用户数据。
auth模块: from django.contrib import auth
进一步详细学习 >>> 点击
auth模块常用方法:
1. 创建超级用户
python manage.py createsuperuser
2. 认证 校验用户名和密码
obj = auth.authenticate(request,username,password)
认证成功返回 对象
失败 None
3. 保存登录状态 记录到session
login(request, user)
4. 注销 删除session
logout(request)
5. 判断登录状态
request.user.is_authenticated()
6. 创建用户
from django.contrib.auth.models import User
# 密码是明文的
User.objects.create(username=username,password=password)
# 密码是密文的 普通用户
User.objects.create_user(**form_obj.cleaned_data)
# 创建超级用户
User.objects.create_superuser(email='',**form_obj.cleaned_data)
7. 密码相关
# 检验密码
request.user.check_password('root1234')
# 设置密码
request.user.set_password('admin1234')
request.user.save()
forms.py文件示例:
from django import forms # from django.forms import widgets from django.core.validators import ValidationError class RegForm(forms.Form): # from django import forms username = forms.CharField( label='用户名', # # 自定义属性实现bootstrap效果 # widget=forms.widgets.TextInput(attrs={'class': 'form-control'}) ) password = forms.CharField( label='密码', min_length=6, widget=forms.widgets.PasswordInput(), ) re_password = forms.CharField( label="确认密码", min_length=6, widget=forms.widgets.PasswordInput(), ) # 自定义初始化函数实现bootstrap效果属性 可以用于全局 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) for field in self.fields: self.fields[field].widget.attrs.update({'class': 'form-control'}) # 用全局钩子函数实现密码一致性验证 def clean(self): pwd = self.cleaned_data.get('password') re_pwd = self.cleaned_data.get('re_password') if pwd == re_pwd: return self.cleaned_data # 注意全局钩子的返回值 self.add_error("re_password", '两次密码不一致') # 让错误信息的显示靠近re_input的输入框 # from django.core.validators import ValidationError raise ValidationError('两次密码不一致') # 钩子函数调用了ValidationError
views.py文件示例:
from django.shortcuts import render, redirect, HttpResponse from django.contrib import auth from django.contrib.auth.decorators import login_required from app01.forms import RegForm from django.contrib.auth.models import User # orm操作需要使用 def login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') # 认证用户 obj = auth.authenticate(request, username=username, password=password) print(obj, type(obj)) if obj: # 记录登录状态 auth.login(request, obj) # 实现一个用户登录的功能。它本质上会在后端为该用户生成相关session数据。 next = request.GET.get('next') if next: return redirect(next) return redirect('/index/') return render(request, 'login.html') # login_requierd()给我们提供的一个装饰器工具,用来快捷的给某个视图添加登录校验。 @login_required # 使index页面的登录状态和login同步 def index(request): # is_authenticated()用来判断当前请求是否通过了认证。 # print(request.user.is_authenticated()) # request.user可获取当前用户名 return render(request, 'index.html') # 注销 def logout(request): auth.logout(request) return redirect('/login/') # 注册 def reg(request): # from app01.forms import RegForm form_obj = RegForm() if request.method == 'POST': form_obj = RegForm(request.POST) if form_obj.is_valid(): # 创建方法一 # username = form_obj.cleaned_data.get('username') # password = form_obj.cleaned_data.get('password') # User.objects.create_user(username=username, password=password) # 创建用户 # 创建方法二 form_obj.cleaned_data.pop('re_password') #不弹出会报错 User() got an unexpected keyword argument 're_password' # User.objects.create_user(is_staff=1, **form_obj.cleaned_data) # 创建用户 # 创建超级用户 # 创建超级用户需要加email User.objects.create_superuser(email='', **form_obj.cleaned_data) # 创建超级用户 return redirect('/login/') return render(request, 'reg.html', {'from_obj': form_obj})
用户对象的属性
user_obj能够拿到认证所用用户表的数据属性,比如username, password等。
其他常用属性含义如下:
is_staff : 用户是否拥有网站的管理权限.
is_active : 是否允许用户登录, 设置为 False,可以在不删除用户的前提下禁止用户登录。
扩展默认的auth_user表
auth_user表是auth模块默认生成的用户表,字段都是固定,如果想要为表新添加字段,可以新建另外一张表然后通过一对一和内置的auth_user表关联。
我们可以通过继承内置的 AbstractUser 类,来定义一个自己的Model类。
这样既能根据项目需求灵活的设计用户表,又能使用Django强大的认证系统了。
from django.contrib.auth.models import AbstractUser
按上面的方式扩展了内置的auth_user表之后,一定要在settings.py中告诉Django,我现在使用我新定义的UserInfo表来做用户认证。写法如下:
# 引用Django自带的User表,继承使用时需要设置
AUTH_USER_MODEL = "app名.UserInfo"
自定义认证系统默认使用的数据表之后,我们就可以像使用默认的auth_user表那样使用我们的UserInfo表了。