zoukankan      html  css  js  c++  java
  • Django-Auth组件

    一、auth组件介绍

    在日常的开发中,我们会必定会写的一个功能就是注册,登录,认证,注销且这部分的代码逻辑基本相似。所以django为了我们内置了一个用户认证组件,auth组件,他属于和我们自己创建的app一个级别

    二、内置属性方法

    auth组件的内置属性与方法都需要数据迁移之后才能使用,当我们数据迁移之后,会在数据库自动生成表格

    image-20201026160047374

    image-20201026160619899

    1.authenticate用户认证

    提供了用户认证功能,即验证用户名以及密码是否正确,一般需要username 、password两个关键字参数。

    如果认证成功(用户名和密码正确有效),便会返回一个 User 对象。

    authenticate()会在该 User 对象上设置一个属性来标识后端已经认证了该用户,且该信息在后续的登录过程中是需要的。

    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') # 明文
            # 第一个参数必须是request对象
            user=auth.authenticate(request,username=name,password=password)
            if user:
                return HttpResponse('登录成功')
            else:
                return HttpResponse('用户名或密码错误')
    

    2.login

    # 表示用户登录了,使用该方法后做了下面两件事
    # 1 存了用户的session
    # 2 以后所有的视图函数,都可以使用request.user,它就是当前登录用户
    auth.login(request,user)
    

    3.logout

    def logout(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_required,则会跳转到django默认的登录URL '/accounts/login/ ' 并传递当前访问url的绝对路径 (登陆成功后,会重定向到该路径)。

    from django.contrib.auth.decorators import login_required
    
    @login_required(login_url='/login/')
    def order(request):
        return HttpResponse('ok')
    

    6.create_user

    # 使用内置的create_user或者create_superuser方法
    user=User.objects.create_user(username=name,password=password)
    user=User.objects.create_superuser(username=name,password=password)
    

    7.check_password

    有了用户,校验密码是否正确

    # 先获取到用户对象
    user = User.objects.filter(username=name).first()
    # 判断密码是否正确
    flag=user.check_password(password)
    

    8.set_password

    修改密码

    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 request.user.check_password(old_pwd):
                # 密码正确再修改
                request.user.set_password(new_pwd)
                # 要手动保存
                request.user.save()
                return redirect('/login/')
            else:
                return HttpResponse('原密码错误')
    

    9.User对象的属性

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

    三、扩展默认的auth_user表

    默认的auth_user表的字段有些情况下不够使用,比如我们需要记录用户的手机号,家庭地址等等,那么就需要扩展该表。

    在扩展的时候,都是在我们之前使用的models

    方式一:一对一

    from django.contrib.auth.models import User
    
    class UserDetail(models.Model):
        phone = models.CharField(max_length=32)
        addr = models.CharField(max_length=32)
        user= models.OneToOneField(to=User)
    

    方式二:继承

    # 步骤一:setting中配置
    AUTH_USER_MODEL = "app01.User"
    # 步骤二:写类,使用这种方式,一开始创建表的时候就得使用
    from django.contrib.auth.models import AbstractUser
    class User(AbstractUser):
        # 也可以重写原来的字段,比如觉得名字字段太短了,username = models.CharField(max_length=128)
        phone = models.CharField(max_length=32)
        addr = models.CharField(max_length=32)
    

    1.后期扩展

    如果项目一开始没有扩展auth_user表,后期想扩展的操作步骤

    1 备份--删库---》重新创建出数据库
    2 所有app的数据迁移记录删除migrations下除了__init__.py都删除
    3 (重要)去源码中删除auth和admin 这俩app的migrations下除了__init__.py都删除
    4 数据迁移,同步到数据库
    5 备份的数据,恢复回去
    

    四、自定义中间表(中介模型)

    1.默认使用ManyToMany,自动创建

    2.完全自己手写第三张表

    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()
        
    # 在book表,author表中,就不需要再添加ForeignKey字段了
    # 手动创建表后添加等,需要自己手动写了。因为这其实是一张自己创建出来的表,在我们逻辑层面和其他表有关系,但是对于数据库本身来说没关系。
    models.AuthorToBook.objects.create(book_id_id=1,author_id_id=1)
    models.AuthorToBook.objects.create(book_id_id=1,author_id_id=2)
    

    3.使用中介模型

    使用中介模型之后,原本多读多的方法,add,set,clear,remove都不能使用了,只能查询。但是查询是有所简便,不需要再经过中间表了。

    # 使用中介模型,即是在手动创建的基础上,在manytomany的关联字段上添加两个参数:
    # through='AuthorToBook',through_fields=('book_id','author_id')
    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 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 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()
        
    # 中介模型的查询,更为简单
    book = models.Book.objects.get(pk=1)
    print(book.authors.all())
    
  • 相关阅读:
    诸神之眼-Nmap(精版,更新中。。。)
    workerman-chat聊天室
    Mysql记录事本
    网站标题、描述、关键词怎么设置?
    什么是谷歌SEO?
    图片加载之性能优化
    前端实现图片懒加载(lazyload)的两种方式
    HTML`CSS_网站页面不同浏览器兼容性问题解决
    从输入url到显示页面,都经历了什么
    什么是mvvm mvc是什么区别 原理
  • 原文地址:https://www.cnblogs.com/chiyun/p/14066883.html
Copyright © 2011-2022 走看看