Auth模块是Django自带的用户认证模块。开发一个网站的时候,无可避免的需要设计实现网站的用户系统。例如用户注册、用户登录、用户认证、注销、修改密码等功能。而Django中内置了强大的用户认证系统也就是auth,它默认使用 auth_user 表来存储用户数据,admin也是使用auth_user表数据,下图是admin的入口界面
auth_user 表
该表在执行迁移命令时自动产生,是Django自带的表,其用于存放用户和管理员数据,默认字段如下所示
有时候这些默认字段不够我们使用,我们可以对其进行拓展,拓展方法有编写一对一表关系、类继承(推荐),类继承方式如下
所示
1. 在 models 文件中导入 AbstractUser类,导入语句如下所示
from django.contrib.auth.models import AbstractUser
2. 创建一个自定义类并继承AbstractUser类,然后编写AbstractUser类中没有的字段并且'不能冲突'
# 拓展auth_user表
class Users(AbstractUser):
# 字段不能与AbstractUser类中的字段冲突
phone = models.BigIntegerField()
addr = models.CharField(max_length=32)
3. 自定义好类后还要去settings配置文件中进行声明,让Django知道现在需要使用自定义的类来进行用户认证,声明
后Django会自动切换参照表,声明语句如下所示
# 声明使用自定义表作为用户验证,声明格式为: 应用名.表名
AUTH_USER_MODEL = 'auth_test.Users'
4. 然后就是使用迁移命令来创建自定义表,需要注意的是,所在的库必须是第一次执行迁移命令才可以,若是原本有残留会
引起异常。自定义表和原本的auth_user表一样,都可以使用auth模块的所有方法。
# 如果auth_user表已经有了,还想扩写
删库、清空项目中所有migration的记录、清空源码中admin,auth俩app的migration的记录
5. 执行完迁移命令,发现自定义表中除了自定义的字段,还自动创建了原本auth_user表中的字段,并且和原本相比多出了
三张表,如下图所示。
createsuperuser 关键字用于创建admin后台管理员用户,在 Run manage.py Task... 中输入即可
createsuperuser 关键字命令全称是 python manage.py createsuperuser
使用后会让你输入用户名密码,并且密码有要求。如果你是自定义字段,会出现问题,可以让自定义字段允许为空。
创建后表中会多出记录,并且密码字段是一个密文的形式,无法直接查看内容。如下所示
此时就可以登录admin后台管理系统,如下图所示
authenticate(request=None, **credentials)
该方法提供了用户认证功能,即验证用户名以及密码是否正确,一般需要username 、password两个关键字参数。
如果认证成功(用户名和密码正确有效),便会返回一个 User 对象,否则返回None
1. 首先需要导入auth 模块,导入语句: from django.contrib import auth
2. 事先准备好简易的表单界面,用于获取输入数据
3. 编写视图函数
class Login(View):
def get(self, request):
return render(request, 'login.html')
def post(self, request):
# 获取用户输入内容
username = request.POST.get('name')
userpwd = request.POST.get('pwd')
# 验证用户名以及密码是否正确
user_obj = auth.authenticate(request, username=username, password=userpwd)
# 如果正确返回用户对象,不正确返回None
print(user_obj)
return render(request, 'login.html')
login(HttpRequest, user)
该方法接受一个HttpRequest对象,以及一个经过认证的User对象。可以在验证成功后进行登录,也就是产生session数据
使用示例
from django.contrib import auth
class Login(View):
def get(self, request):
return render(request, 'login.html')
def post(self, request):
username = request.POST.get('name')
userpwd = request.POST.get('pwd')
# 验证用户名密码是否正确,正确返回用户对象
user_obj = auth.authenticate(request, username=username, password=userpwd)
if user_obj:
# 验证正确后,调用login方法传入request对象和用户对象,用于生成session数据
auth.login(request, user_obj)
return render(request, 'login.html')
is_authenticated()可以用来判断当前是否是否登录,也就是是否有session数据
查看用户状态
查看用户登录状态使用的方法是request.user,若已经登录返回用户对象,若没有登录返回匿名用户AnonymousUser
使用示例
class ExitLogin(View):
def get(self, request):
print(request.user)
return HttpResponse('查看是否登录')
判断是否登录
由于方法 request.user 返回的都是字符串,不好进行判断。
可以使用方法 request.user.is_authenticated(),若是没有登录,该方法会返回False,反之返回True
使用示例
class Check(View):
def get(self, request):
# print(request.user)
# 判断是否登录
if request.user.is_authenticated():
# 可以打印用户名和密码
print(request.user.username)
print(request.user.password)
return HttpResponse('查看是否登录')
登录装饰器也可以直接使用自带的,首先要导入模块,导入语句:
from django.contrib.auth.decorators import login_required
login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None)
'login_url': 该参数指定没有登录时跳转的地址,一般跳转到登录界面
局部配置
使用示例
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
@method_decorator(login_required(login_url='/login/'), name='get')
class Index(View):
def get(self, request):
return HttpResponse('这是Index')
'''由于我这里使用的是类的形式,所以导入了模块 method_decorator '''
1. @login_required()
直接使用结果 http://127.0.0.1:8000/accounts/login/?next=/index/
2. @login_required(login_url='/login/')
路由为 http://127.0.0.1:8000/login/?next=/index/
全局配置
除了在装饰器中使用 login_url 参数来指定路由外,还可以在全局中指定,在settings配置文件中指定后,所有的装饰器
都不需要添加login_url参数了,设置方式如下所示
# 配置未登录时重定向的路由
LOGIN_URL = '/login/'
登录视图函数
可以在其验证成功后跳转回原来界面
class Login(View):
def get(self, request):
return render(request, 'login.html')
def post(self, request):
username = request.POST.get('name')
userpwd = request.POST.get('pwd')
user_obj = auth.authenticate(request, username=username, password=userpwd)
if user_obj:
auth.login(request, user_obj)
# 获取用户上级页面,没有使用默认值接收
path = request.GET.get('next')
if path:
res = redirect(path)
else:
res = redirect('/admin/')
return res
return render(request, 'login.html')
该函数接受一个HttpRequest对象,无返回值。
当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错
使用示例
from django.contrib import auth
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
class Exit(View):
@method_decorator(login_required)
def get(self, request):
auth.logout(request)
return HttpResponse('退出登录')
auth 提供的一个检查密码是否正确的方法,需要提供当前请求用户的密码。
密码正确返回True,否则返回False。
使用方式
is_right = request.user.check_password(pwd)
request.set_password(password) auth 提供的一个修改密码的方法,接收新密码作为参数
request.user.save() 将修改操作保存到数据库
使用示例
class Set(View):
@method_decorator(login_required)
def get(self, request):
return render(request, 'set.html')
def post(self, request):
old_pwd = request.POST.get('old_pwd')
new_pwd = request.POST.get('new_pwd')
is_right = request.user.check_password(old_pwd)
if is_right:
request.user.set_password(new_pwd)
request.user.save()
return render(request, 'set.html')
auth 提供的一个创建新用户的方法,需要提供必要参数(username、password)等。
使用示例
# 导入User表
from django.contrib.auth.models import User
from auth_test import models
class Create_user(View):
def get(self, request):
users = models.Users.objects.create_user(username='u1', password='123456u1'
return HttpResponse('注册用户')
'''需要注意的是,我这里拓展了auth_user表,使用的是models中的自定义类'''
auth 提供的一个创建新的超级用户的方法,需要提供必要参数(username、password)等。
使用示例
from django.contrib.auth.models import User
user = User.objects.create_superuser(username='用户名',password='密码'...)
后台管理系统提供了快速编辑表内容的功能,需要在应用中的 admin.py 文件中注册表,如下示例
from django.contrib import admin
from app01 import models
# Register your models here.
admin.site.register(models.Role)
admin.site.register(models.User)
admin.site.register(models.Userinfo)
admin.site.register(models.Permission)
注册完的结果如下图所示,点击表名即可修改表内容
定制显示的列。可以指定后台管理系统中表的展示字段,并且如果有verbose_name则会以别名作为字段名。
首先在注册表前定义一个类,然后注册类时将该类作为参数传入,如下示例
from django.contrib import admin
from app01 import models
# Register your models here.
class UserConfig(admin.ModelAdmin):
list_display = ['name', 'pwd']
class UserInfoConfig(admin.ModelAdmin):
list_display = ['first_name', 'last_name', 'phone', 'addr']
# 在注册时添加类名作为参数
admin.site.register(models.User, UserConfig)
admin.site.register(models.Userinfo, UserInfoConfig)
改变表的链接。在后台管理系统中修改表内容时,默认是按照第一个字段作为链接跳转到修改界面,虽然也可以通过list_display
来改变第一个字段名称。实际上list_display_links
参数可以修改链接字段
from django.contrib import admin
from app01 import models
# Register your models here.
class UserConfig(admin.ModelAdmin):
list_display_links = ['pwd']
admin.site.register(models.User, UserConfig)
也可以设置多个字段作为链接字段例如 list_display_links = ['name', 'pwd']
该参数可以生成一个搜索框,搜索包含指定内容的数据。搜索的字段需要指定,可以有多个字段,当有多个字段的时候,字段之间是或的关系俩个字段都会去查找指定内容。
from django.contrib import admin
from app01 import models
class UserConfig(admin.ModelAdmin):
list_display = ['name', 'pwd']
list_display_links = ['name', 'pwd']
search_fields = ['name', 'pwd']
admin.site.register(models.User, UserConfig)
该参数可以定制右侧快速筛选,筛选字段可以自定义,一般填写外键字段,普通字段没有实际意义
from django.contrib import admin
from app01 import models
class UserConfig(admin.ModelAdmin):
list_display = ['name', 'pwd']
list_display_links = ['name', 'pwd']
search_fields = ['name', 'pwd']
# 定义右侧快速筛选
list_filter = ['name', 'pwd']
admin.site.register(models.User, UserConfig)
在后台管理系统中默认提供了一个名为 Delete selected users 的方法,该方法作用为删除某一个数据。除了这个方法我们也可以自定义一个方法。
from django.contrib import admin
from app01 import models
# Register your models here.
class UserConfig(admin.ModelAdmin):
# 自定义方法
def myfunc(self, request, queryset):
pass
# 给自定义方法起名字
myfunc.short_description = '我的自定义方法'
# 自定义queryset的操作函数
actions = [myfunc, ]
admin.site.register(models.User, UserConfig)
该参数可以设置在查看表数据时可以直接编辑某个字段数据,而不用点开编辑页。需要注意的是:由于设置的字段可以直接编辑,所以不能作为跳转编辑页链接的字段,并且还要展示多个字段。
from django.contrib import admin
from app01 import models
# Register your models here.
class UserConfig(admin.ModelAdmin):
# 设置展示的字段
list_display = ['name', 'pwd']
# 设置链接的字段
list_display_links = ['pwd']
# 设置直接编辑的字段
list_editable = ['name']
admin.site.register(models.User, UserConfig)
对Date和DateTime类型进行搜索
详细页面,如果有其他表和当前表做FK,那么详细页面可以进行动态增加和删除
针对FK和M2M字段变成以Input框形式
详细页面时,显示字段的字段
详细页面时,显示字段的字段
详细页面时,排除的字段
详细页面时,只读字段
详细页面时使用fieldsets标签对数据进行分割显示
列表时,数据排序规则
详细页面时,使用radio显示选项(FK默认使用select)
用于定制用户请求时候表单验证