我们在前面做了好几个用户登录验证的页面,但是Django还为我们直接提供了一个auth模块可以直接实现用户管理的需求。
用户管理
auth模块使用的是Django迁移出来的数据库里的一个叫auth_user的table存储用户信息,默认的类是下面的
from django.contrib.auth.models import User
用户管理
那这个用户是怎么来的呢?我们在Django数据库可视化操作一节讲过了,可以通过下面的命令来创建超级用户
python3 manage.py createsuperuser
超级用户创建完毕以后,运行项目,访问http://127.0.0.1:8000/admin/,用刚才创建的超级用户登录,然后里面就有用户管理的页面(http://127.0.0.1:8000/admin/auth/user/add/)
我们从下面的案例来直接看一下auth模块是怎么使用的
from django.contrib import auth def login(request): if request.method == 'POST': username = request.POST.get('user') pwd = request.POST.get('pwd') user = auth.authenticate(username=username,password=pwd)#用户校验 if user: auth.login(request,user) #绑定用户至request return redirect('/auth/home') #登录成功跳转到别的页面(重定向) return render(request,'login.html',{'page_url':'/auth/login'})
上面的代码中主要就两点要注意的,
一个是我们用auth.authenticate来对用户名和密码进行校验,如果和数据库中存储的内容一致user值就为username,否则就是Null。登录成功,用另一个方法(auth.login)把user和request进行绑定,在别的页面上就可以用这个用户
并且这里还有一个小知识点,这里还用到了session,
------------恢复内容开始------------
我们在前面做了好几个用户登录验证的页面,但是Django还为我们直接提供了一个auth模块可以直接实现用户管理的需求。
用户管理
auth模块使用的是Django迁移出来的数据库里的一个叫auth_user的table存储用户信息
用户管理
那这个用户是怎么来的呢?我们在Django数据库可视化操作一节讲过了,可以通过下面的命令来创建超级用户
python3 manage.py createsuperuser
超级用户创建完毕以后,运行项目,访问http://127.0.0.1:8000/admin/,用刚才创建的超级用户登录,然后里面就有用户管理的页面(http://127.0.0.1:8000/admin/auth/user/add/)
通过代码创建用户
除了用前面说的那个通过界面添加用户,我们还可以通过代码来创建用户
虽然用户也是一个通过ORM对应数据库的类,但是是绝对不能使用下面的方式来创建用户的
User.objects.create(username='',password='')
用这种方法创建用户是可以在auth_user表中添加数据的,但是密码是按照明文存储的,在登录进行校验的时候就会报错。所以可以用下面这个方式来创建
User.objects.create_superuser(username='',password='') #创建超级用户 User.objects.create_user(username=,password='') #创建普通用户
用上面的方法就可以创建新的用户
用户密码修改
密码修改是对用户对象来进行的
user_obj.set_password("new password") user_obj.save()
我们从下面的案例来直接看一下auth模块是怎么使用的
from django.contrib import auth def login(request): if request.method == 'POST': username = request.POST.get('user') pwd = request.POST.get('pwd') user = auth.authenticate(username=username,password=pwd)#用户校验 if user: auth.login(request,user) #绑定用户至request return redirect('/auth/home') #登录成功跳转到别的页面(重定向) return render(request,'login.html',{'page_url':'/auth/login'})
上面的代码中主要就两点要注意的,
一个是我们用auth.authenticate来对用户名和密码进行校验,如果和数据库中存储的内容一致user值就为username,否则就是Null。登录成功,用另一个方法(auth.login)把user和request进行注入,在别的页面上就可以用这个用户
并且这里还有一个小知识点,这里还用到了session,我们看一下他的源代码
class AuthenticationMiddleware(MiddlewareMixin): def process_request(self, request): assert hasattr(request, 'session'), ( "The Django authentication middleware requires session middleware " "to be installed. Edit your MIDDLEWARE%s setting to insert " "'django.contrib.sessions.middleware.SessionMiddleware' before " "'django.contrib.auth.middleware.AuthenticationMiddleware'." ) % ("_CLASSES" if settings.MIDDLEWARE is None else "") request.user = SimpleLazyObject(lambda: get_user(request))
所以这个用户的中间件还涉及到了Session的操作,可以保存用户登录的状态,就不用
auth模块常用方法
除了前面讲的用户验证和注入request的方法外,还有几个方法是要了解的
注销
auth.logout()
登录状态
登录状态的验证有两种方法:
函数方法is_authenticated
这个方法一般用来放在函数里,在已经登录的状态下返回值为1,否则为0。
还有一种方法是用装饰器
from django.contrib.auth.decorators import login_required @login_required def home(request): print(request.user.is_authenticated) print(request.user.username) # return HttpResponse('home页面'+request.user.username+request.user.password) return HttpResponse('home页面'+request.user.username+"<a href='/auth/logout'>注销</a>")
这个装饰器在使用的时候是要在settings.py指定一个未登录状态的跳转URL的。
LOGIN_URL = '/test/'
在被装饰的视图没有登录的时候被重定向到这个指定的URL。
本章最开始的时候我们在数据库中用desc查了默认的auth_user表里的字段,但是有些时候我们需要一些其他的字段,这时候就涉及到auth表的扩展。比方我们要记录下每个用户的电话号
方案1:一对一关联
第一个思路是利用一对一的关系重新创建一个类
from django.contrib.auth.models import User class UserDetail(models.Model): phone = models.CharField(max_length=11) #注意下面的关联时候省略了引号 user = models.OneToOneField(to=User)
一定要注意,在建立一对一关联的时候,关联的对象里没有加了个引号"User",而在前面讲一对一关联的时候我们是加了引号的,因为我们的User类是从额外的包里导入的,也就是说在创建这个额外的表的时候已经有了这个User类了。
加双引号的用法是在我们定义这个类的时候还没有声明那个要关联的类(可能代码中先写的UserDetail再写的User),那么就需要让解释器从整个py文件中通过反射找到User这个字符串对应的变量。
方案2:利用类的继承
上面的方法虽然可以用,但是额外的创建了一个一对一的外键。所以一般情况我们不太推荐使用。那么既然类是可以继承的,而User原本就是一个类,那么我们就可以重新写一个类继承了User以后在添加新的字段就可以了。
from django.contrib.auth.models import AbstractUser class My_User(AbstractUser): phone = models.CharField(max_length=11)
要注意的是,在这个自定义的Auth类里我们继承的并不是User,并且在定义以后我们还要在settings.py中声明我们要用的自定义类
# 如果使用继承的方式 使用内置的auth模块,要在settings.py里面配置 默认用户认证时使用的是哪张表 AUTH_USER_MODEL = 'app01.My_User' #"app名.表名"
还有要注意的地方,就是我们在使用Auth里的User的时候,就;不能想前面一样对User类进行操作了,而是要导入我们自定义的这个类