python-django_auth组件介绍_内置属性方法_User对象的属性_扩展默认的auth_user表_自定义中间表

django auth

1. auth组件介绍

Auth模块是Django自带的用户认证模块:

	我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统。此时我们需要实现包括用户注册、用户登录、用户认证、注销、修改密码等功能,这还真是个麻烦的事情呢。

	Django作为一个完美主义者的终极框架,当然也会想到用户的这些痛点。它内置了强大的用户认证系统--auth,它默认使用 auth_user 表来存储用户数据。

2. auth模块常用方法

from django.contrib import auth
1. authenticate
# authenticate()	
    提供了用户认证功能,即验证用户名以及密码是否正确,一般需要username 、password两个关键字参数。
	如果认证成功(用户名和密码正确有效),便会返回一个 User 对象。
	authenticate()会在该 User 对象上设置一个属性来标识后端已经认证了该用户,且该信息在后续的登录过程中是需要的。

# 用法:
	user = authenticate(username='usernamer',password='password')
    
# 示例
from django.contrib import auth

def login(request):
    if request.method=='GET':
        return render(request,'login.html')
    else:
        name=request.POST.get('name')
        password=request.POST.get('password') # 明文
        # 方案行不通,密码是密文的,永远匹配不成功
        # user=User.objects.filter(username=name,password=password)
        # 使用此方案
        # 第一个参数必须是request对象
        # username和password
        user=auth.authenticate(request,username=name,password=password)
        if user:
            return HttpResponse('登录成功')
        else:
            return HttpResponse('用户名或密码错误')
2. login
# login(HttpRequest, user)
	该函数接受一个HttpRequest对象,以及一个经过认证的User对象 表示用户登录了
	该函数实现一个用户登录的功能。它本质上会在后端为该用户生成相关session数据。

# 1 存了session
# 2 以后所有的视图函数,都可以使用request.user,它就是当前登录用户
	auth.login(request,user)
 
# 示例
from django.contrib.auth import authenticate, login
   
def my_view(request):
    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(username=username, password=password)
    if user is not None:
        login(request, user)
        # Redirect to a success page.
        ...
    else:
        # Return an 'invalid login' error message.
        ...    
3. logout
# logout(request) 	
    该函数接受一个HttpRequest对象,无返回值。
	当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错。

# 用法:
from django.contrib.auth import logout
   
def logout_view(request):
	# 后续再访问视图函数,就没有当前登录用户了request.user(匿名用户AnonymousUser)
    auth.logout(request)
    return redirect('/index/')
4. is_authenticated
# is_authenticated 返回True或者False
	用来判断当前请求是否通过了认证 即判断用户是否登录

# 用在视图中
if request.user.is_authenticated:
    print('用户登录了')
else:
    print('用户没有登录,匿名用户')

# 用在模板中
{% if request.user.is_authenticated %}
{{ request.user.username }} 登录了
    {% else %}
    <a href="/login/">滚去登录</a>
{% endif %}
5. login_requierd
# login_requierd()
	auth 给我们提供的一个装饰器工具,用来快捷的给某个视图添加登录校验。
    装饰器,装饰在视图函数上,只要没有登录,就进不来
    
# 必须登录后才能访问
from django.contrib.auth.decorators import login_required
      
@login_required
def my_view(request):
  ...

@login_required(login_url='/login/')

	若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/ ' 并传递当前访问url的绝对路径 (登陆成功后,会重定向到该路径)。

	如果需要自定义登录的URL,则需要在settings.py文件中通过LOGIN_URL进行修改。
	示例:
		LOGIN_URL = '/login/'  # 这里配置成你项目登录页面的路由
6. create_user/superuser
# create_user
	auth 提供的一个创建新用户的方法,需要提供必要参数(username、password)等
    
# create_superuser
	auth 提供的一个创建新的超级用户的方法,需要提供必要参数(username、password)等  

# 使用内置的create_user或者create_superuser方法	
from django.contrib.auth.models import User

user=User.objects.create_user(username=name,password=password)

user=User.objects.create_superuser(username=name,password=password)
7. check_password
# check_password(password)
	auth 提供的一个检查密码是否正确的方法,需要提供当前请求用户的密码
	密码正确返回True,否则返回False

# 用法:
	ok = user.check_password('密码')
    
# 示例
# 有了用户,校验密码是否正确
# 先获取到用户对象
user = User.objects.filter(username=name).first()
# 判断密码是否正确
flag=user.check_password(password)
8. set_password
# set_password(password)
	auth 提供的一个修改密码的方法,接收 要设置的新密码 作为参数
	注意:设置完一定要调用用户对象的save方法

# 用法:
    user.set_password(password='')
    user.save()
    
# 示例 一个修改密码的简单示例
@login_required
def set_password(request):
    user = request.user
    err_msg = ''
    if request.method == 'POST':
        old_password = request.POST.get('old_password', '')
        new_password = request.POST.get('new_password', '')
        repeat_password = request.POST.get('repeat_password', '')
        # 检查旧密码是否正确
        if user.check_password(old_password):
            if not new_password:
                err_msg = '新密码不能为空'
            elif new_password != repeat_password:
                err_msg = '两次密码不一致'
            else:
                user.set_password(new_password)
                user.save()
                return redirect("/login/")
        else:
            err_msg = '原密码输入错误'
    content = {
        'err_msg': err_msg,
    }
    return render(request, 'set_password.html', content)

3. User对象属性

# User对象属性
	username  password
	is_staff:     用户是否拥有网站的管理权限,是否可以登录到后台管理
	is_superuser: 是否是超级管理员(如果is_staff=1,可以任意增删查改任何表数据)
	is_active:    是否允许用户登录, 设置为 False
        		  可以在不删除用户的前提下禁止用户登录(三次密码输入错误禁用用户)

4. 扩展默认的auth_user表

内置的认证系统这么好用,但是auth_user表字段都是固定的那几个,我在项目中没法拿来直接使用啊!
比如,我想要加一个存储用户手机号的字段,怎么办?
聪明的你可能会想到新建另外一张表然后通过一对一和内置的auth_user表关联,这样虽然能满足要求但是有没有更好的实现方式呢?
我们可以通过继承内置的 AbstractUser 类,来定义一个自己的Model类。
这样既能根据项目需求灵活的设计用户表,又能使用Django强大的认证系统了。

# 内置的auth_user表,要加字段,加不了,扩展该表
	方式一: 一对一
    方式二: 通过继承
    
    # 方式二:通过继承,一定要记住再setting中配置
    # 重点:使用这种方式,一开始就要用
    from django.contrib.auth.models import AbstractUser
    class User(AbstractUser):
        # id=models.AutoField(primary_key=True)
        # username = models.CharField(max_length=128)
        phone = models.CharField(max_length=32)
        addr = models.CharField(max_length=32)
        
    # setting.py中
    	AUTH_USER_MODEL = "app01.User"
        
# 注意1
	按上面的方式扩展了内置的auth_user表之后,一定要在settings.py中告诉Django,我现在使用我新定义的UserInfo表来做用户认证。写法如下:
    
    # 引用Django自带的User表,继承使用时需要设置
    AUTH_USER_MODEL = "app名.UserInfo"  
 
# 注意2
	一旦我们指定了新的认证系统所使用的表,我们就需要重新在数据库中创建该表,而不能继续使用原来默认的auth_user表了
    
# 如果项目一开始没有扩展auth_user表,后期想扩展的操作步骤
1. 备份--删库---》重新创建出数据库
2. 所有app的数据迁移记录删除migrations下除了__init__.py都删除
3. 去源码中删除auth和admin 这俩app的migrations下除了__init__.py都删除
4. 数据迁移,同步到数据库
5. 备份的数据,恢复回去

5. 自定义中间表(中介模型)

1. 示例一

# 多对多关系中,第三张表的建立
	-默认使用ManyToMany,自动创建
    -使用中介模型
    	-即手动创建第三张表,又要使用好用的查询
    -完全自己写第三张表
    
# 使用中介模型
class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='AuthorDatail', to_field='nid', unique=True, on_delete=models.CASCADE)

class AuthorDatail(models.Model):
    nid = models.AutoField(primary_key=True)
    telephone = models.BigIntegerField()
    birthday = models.DateField()
    addr = models.CharField(max_length=64)

class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField()

    publish = models.ForeignKey(to='Publish', to_field='nid', on_delete=models.CASCADE)
    # 当前在哪个表中,元组中的第一个参数就是 表明_id
    authors=models.ManyToManyField(to='Author',through='AuthorToBook',through_fields=('book_id','author_id'))
    def __str__(self):
        return self.name

class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

class AuthorToBook(models.Model):
    nid = models.AutoField(primary_key=True)
    book_id = models.ForeignKey(to=Book, to_field='nid', on_delete=models.CASCADE)
    author_id = models.ForeignKey(to=Author, to_field='nid', on_delete=models.CASCADE)
    date=models.DecimalField()
    
# s1.py  
import os

if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day76.settings")
    import django
    django.setup()
    from app01 import models
    # 金瓶梅这本书是lqz和egon写的
    # book=models.Book.objects.get(pk=1)
    # # book.authors.add(1,2) # 用不了了
    # # 只能手动写
    # models.AuthorToBook.objects.create(book_id_id=1,author_id_id=1)
    # models.AuthorToBook.objects.create(book_id_id=1,author_id_id=2)

    # 金瓶梅这本书所有的作者

    # book = models.Book.objects.get(pk=1)
    # res=models.AuthorToBook.objects.filter(book_id=book)
    # print(res)

    # book = models.Book.objects.get(pk=1)
    # print(book.authors.all())

    # 金瓶梅这本书是lqz和egon写的 add ,remove, clear,set
    # 但是连表操作,book.authors这些都能用
    book = models.Book.objects.get(pk=1)
    book.authors.add(1,2) # 不能用了

2. 示例二

# 全自动
	利用orm自动帮我们创建第三张关系表
    
    # 示例
    class Book(models.Model):
        name = models.CharField(max_length=32)
        authors = models.ManyToManyField(to='Author')

    class Author(models.Model):
        name = models.CharField(max_length=32)
        
    """
    优点:代码不需要你写 非常的方便 还支持orm提供操作第三张关系表的方法...
    不足之处:第三张关系表的扩展性极差(没有办法额外添加字段...)
    """
    
# 纯手动
	# 示例
    class Book(models.Model):
        name = models.CharField(max_length=32)

    class Author(models.Model):
        name = models.CharField(max_length=32)

    class Book2Author(models.Model):
        book_id = models.ForeignKey(to='Book')
        author_id = models.ForeignKey(to='Author')
        
    """
    优点:第三张表完全取决于你自己进行额外的扩展
    不足之处:需要写的代码较多,不能够再使用orm提供的简单的方法
    不建议使用该方式
    """

# 半自动
	# 示例
    class Book(models.Model):
        name = models.CharField(max_length=32)
        authors = models.ManyToManyField(to='Author',
                                         through='Book2Author',
                                         through_fields=('book','author')
                                         )
        
    class Author(models.Model):
        name = models.CharField(max_length=32)
        # books = models.ManyToManyField(to='Book',
        #                                  through='Book2Author',
        #                                  through_fields=('author','book')
        #                                  )
        
    class Book2Author(models.Model):
        book = models.ForeignKey(to='Book')
        author = models.ForeignKey(to='Author')
        
    """
    through_fields字段先后顺序
        判断的本质:
            通过第三张表查询对应的表 需要用到哪个字段就把哪个字段放前面
        简化判断
            当前表是谁 就把对应的关联字段放前面

    半自动
    	可以使用orm的正反向查询 但是没法使用add,set,remove,clear这四个方法
    """

# 总结
	需要掌握的是全自动和半自动 为了扩展性更高 一般我们都会采用半自动
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要实现将注册界面输入的用户名和密码存入auth_user库中,可以按照以下步骤进行操作: 1. 在django项目中新建一个app,用于处理用户注册功能。 2. 在该app中创建一个名为`views.py`的文件,用于处理用户注册请求。可以创建一个名为`register`的函数,接收`request`参数,处理用户注册请求。 3. 在`register`函数中,需要先根据`request`参数获取用户输入的用户名和密码。 4. 调用Django提供的`User`模型的`create_user`方法,将用户名和密码存入`auth_user`库中。可以在`models.py`文件中导入`User`模型,然后在`register`函数中调用`User`模型的`create_user`方法进行存储。 5. 如果注册成功,可以将用户重定向到登录页面或其他页面。如果注册失败,可以给用户提示错误信息。 下面是一个简单的代码示例: ```python # views.py from django.shortcuts import render, redirect from django.contrib.auth.models import User def register(request): if request.method == 'POST': # 获取用户输入的用户名和密码 username = request.POST.get('username') password = request.POST.get('password') # 将用户名和密码存入auth_user库中 user = User.objects.create_user(username, password=password) user.save() # 注册成功后重定向到登录页面 return redirect('/login/') else: # 显示注册页面 return render(request, 'register.html') ``` 在上面的代码中,`register`函数首先判断请求方法是否为`POST`,如果是则获取用户输入的用户名和密码。然后调用`User`模型的`create_user`方法,将用户名和密码存入`auth_user`库中。最后重定向到登录页面。 需要注意的是,上面的代码只是一个简单的示例,实际开发中还需要进行更多的错误处理和安全性检查。例如,需要验证用户名是否已被注册、密码是否符合要求等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I believe I can fly~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值