django的auth模块 一、auth模块是什么? 二、auth模块常用方法 三、User对象的属性 四、扩展默认的auth_user表 五、自定义中间表(中介模型)
一、auth模块是什么?
开发网站的时候可避免的需要设计实现网站的用户系统。此时我们需要实现包括用户注册、用户登录、用户认证、注销、修改密码等功能。 Django内置了强大的用户认证系统- - auth,它默认使用 auth_user 表来存储用户数据。
二、auth模块常用方法
from django. contrib import auth
authenticate( ) 方法提供了用户认证功能,即验证用户名及密码是否正确,一般需要username、password两个关键字参数(参数名不能随意填,要与数据库中auth表字段名一样)- 如果验证成功会返回一个user对象- authenticate( ) 会在该 User 对象上设置一个属性来标识后端已经认证了该用户,且该信息在后续的登录过程中是需要的。from django. contrib import authfrom django. contrib. auth import authenticate, login def login ( request) : username = request. POST[ 'username' ] password = request. POST[ 'password' ] user = auth. authenticate( request, username= username, password= password) if user: return redirect( '/index/' ) else : return HttpResponse( 'username or password error' )
- 此函数接受的是一个HTTPRequest对象,以及一个经过认证的User对象- 此函数实现一个用户登录的功能,本质上会在后端为该用户生成相关session数据- 调用了login后,以后所有的视图函数都可以使用request. user,它就是当前登录用户
用法示例:
from django. contrib import authfrom django. contrib. auth import authenticate, login def login ( request) : username = request. POST[ 'username' ] password = request. POST[ 'password' ] user = auth. authenticate( request, username= username, password= password) if user: auth. login( request, user) return redirect( '/index/' ) else : return HttpResponse( 'username or password error' )
- 还函数接受一个HttpRequest对象,没有返回值- 调用该函数时,当前请求的session信息会被全部清除,该用户即使没有登录,使用该函数也不会报错
用法示例:
from django. contrib. auth import logoutfrom django. contrib import authdef logout_view ( request) : auth. logout( request) return redirect( '/login_view/' )
def myview ( request) : if not request. user. is_authenticated( ) : return redirect( f'{settings.LOGIN_URL}?next={request.path}' )
LOGIN_URL = '/login/' from django. contrib. auth. decorators import login_required @login_requireddef my_view ( request) : pass
create_user() 和 create_superuser() auth提供的一个创建新用户/ 超级用户 的方法,需要提供必要的参数(username、password)等from django. contrib. auth. models import user user1 = User. objects. create_user( username= '#用户名1' , password= '#密码1' , email= '#邮箱地址1' . . . ) user2 = User. objects. create_super_user( username= '#用户名2' , password= '#密码2' , email= '#邮箱2' . . . )
flag = user. check_password( '#密码' )
auth提供的一个修改密码的方法,接受要设置的新密码作为参数
用法示例:
def change_password ( request) : if request. method == 'GET' : return render( request, 'change_pwd.html' ) else : old_pwd = request. POST. get( 'old_pwd' ) new_pwd = request. POST. get( 'new_pwd' ) re_new_pwd = request. POST. get( 're_new_pwd' ) if new_pwd == old_pwd: if request. user. check_password( old_pwd) : request. user. set_password( new_pwd) request. user. save( ) return redirect( '/login/' ) else : return HttpResponse( '旧密码不正确' ) else : return HttpResponse( '两次密码输入不一致' )
三、User对象的属性
- User对象属性:username,password- is_staff : 用户是否拥有网站的管理权限, ( 即能不能登录到后台管理) - is_superuser : 是否是超级管理员(权限更高,如果is_staff= 1 , 可以任意增删改查任何数据)- is_active : 是否允许用户登录,设置成False ,可以在不删除用户的前提下禁止用户登录
四、扩展默认的auth_user表
内置的auth_user表字段是固定的,项目中往往需要给它添加字段,但是直接改是不行的,拓展该表有如下两个方式:
方式一:通过关联 建立一张表,通过一对一和内置的auth_user表相关联:
from django. contrib. auth. models import Userclass UserDetail ( models. Model) : phone = models. CharField( max_length= 32 ) addr = models. CharField( max_length= 32 ) user = models. OneToOneField( to= User)
方式二:通过继承 继承内置的AbstractUser,定义一个Model类 这样就可以根据项目的需求灵活设计用户表,又能使用django强大的认证系统
PS:1. 这种方式一开始就要把类建出来,不能中途再试图新增字段,
2. 数据库中的表名就不是 “auth_user” 了,而是变成了 “app01_user”
代码示例:
from django. contrib. auth. models import AbstractUserclass User ( AbstractUser) : phone = models. CharField( max_length= 32 ) addr = models. CharField( max_length= 32 ) AUTH_USER_MODEL = "app01.User"
如果项目一开始没有扩展auth_user表,后期有了加字段的需求: 1 、备份- - > 删库- - > 重新创建数据库2 、所有的app的数据迁移记录删除migrations记录,(除了__init__. py全部都删除)3 、去源码中删除auth和admin这两个app的migrations下除了__init__. py的记录文件4 、数据迁移,同步到数据库中5 、备份的数据,恢复回去
五、自定义中间表(中介模型)
###1、创建多对多关联关系的三种方式
class Book ( models. Model) : name = models. CharField( max_length= 32 ) price = models. DecimalField( max_digits= 5 , decimal_places= 5 ) class Author ( models. Model) : name = models. CharField( max_length= 32 ) class AuthorToBook ( models. Model) : author = models. ForeignKey( to= "Author" , on_delete= models. CASCADE) book = models. ForeignKey( to= "Book" , on_delete= models. CASCADE)
方式一这种建法就没法用 book.authors.add(1,2) 这种关联方法了,因为book表中没有authors字段,只能手动写:
book = models. Book. objects. get( pk= 1 ) models. AuthorToBook. create( book_id= 1 , author_id= 1 ) models. AuthorToBook. create( book_id= 1 , author_id= 2 ) book1 = models. Book. objects. filter ( name= '西游记' ) . first( ) res = models. AuthorToBook. objects. filter ( book= book1) print ( res)
方式二:通过ManyToManyField自动创建第三张表 class Book ( models. Model) : name = models. CharField( max_length= 32 ) class Author ( models. Model) : name = models. CharField( max_length= 32 , verbose_name= "作者姓名" ) books = models. ManyToManyField( to= "Book" )
class Book ( models. Model) : nid = models. AutoField( primary_key= True ) name = models. CharField( max_length= 32 ) authors = models. ManyToManyField( to= "Author" , through= "AuthorToBook" , through_fields= ( "book" , "author" ) ) class Author ( models. Model) : nid = models. AutoField( primary_key= True ) name = models. CharField( max_length= 32 ) class AuthorToBook ( models. Model) : author = models. ForeignKey( to= "Author" , to_field= 'nid' , on_delete= models. CASCADE) book = models. ForeignKey( to= "Book" , to_field= 'nid' , on_delete= models. CASCADE)
当我们需要在第三张关系表中存储额外的字段时,就要使用中介模型的方式了,
但是,用这种方式创建的多对多的关联关系,无法使用set、remove、clear、add方法来管理来管理多对多的关系了,因为第三张表中不一定就只有author和book两个字段
需要通过第三张表的model来管理多对多关系(可以使用book.authors):
book = models. Book. objects. get( pk= 1 ) print ( book. authors. all ( ) )