• 用户认证系统 django.contrib.auth模块


    一 导入auth模块

    from django.contrib.auth.models import User
    from django.contrib import auth

    auth模块的操作针对的就是auth_user表

    二 auth模块的方法

      1 authenticate() 用户验证函数。验证成功,返回一个名称为用户登录名的User对象,这个对象可以调用auth_user表中的属性。验证失败,返回None。

    def login(request):
        if request.method=='POST':
            username=request.POST.get('username')
            password=request.POST.get('password')
            user=auth.authenticate(username=username,password=password)
            print(user,type(user))
            return render(request,'login.html')
        return render(request,'login.html')

      输出:

    zuo <class 'django.contrib.auth.models.User'>

      2 login(request,user) 记录session功能

     user=auth.authenticate(username=username,password=password)
            if user:
                auth.login(request,user)
                return redirect('/index/')

      3 logout(request) 注销

      核心 代码 request.session.flush()

     auth.logout(request)

      PS  request.user。获取当前登录的用户,返回值是一个对象。 用在index页面。确定当前是否有用户登录。如果不是匿名,说明login登录成功。如果是匿名,说明login登录不成功,跳转login页面。

      一个AUTH_USER_MODEL 类型的对象,表示当前登录的用户。如果用户当前没有登录,user 将设置为django.contrib.auth.models.AnonymousUser 的一个实例。你可以通过is_authenticated() 区分它们。

      user 只有当Django 启用AuthenticationMiddleware 中间件时才可用。

      没有用户时:

    def index(request):
    
        username=request.user
        print(username,type(username))

      输出:

    AnonymousUser <class 'django.utils.functional.SimpleLazyObject'>

      有用户时:

      输出

    zuo <class 'django.utils.functional.SimpleLazyObject'>

    三 User对象的API

      1 is_authenticated() 返回布尔值,判断用户是否登录

      2 创建新用户

        User.objects.create_user(username='',password='')

      3 修改密码

        user=User.objects.get(username='xx')

        user.set_password('新密码')      user是对象

        user.save()

    四 form表单提交文件

      预备知识:

      request.FILES

        一个类似于字典的对象,包含所有的上传文件。FILES 中的每个键为<input type="file" name="" /> 中的name

        注意,FILES 只有在请求的方法为POST 且提交的<form> 带有enctype="multipart/form-data" 的情况下才会包含数据。否则,FILES 将为一个空的类似于字典的对象。

        示例:正确的情况

    <MultiValueDict: {'one': [<InMemoryUploadedFile: 新建文本文档.txt (text/plain)>]}>

         [<InMemoryUploadedFile: 新建文本文档.txt (text/plain)>] 可以通过file_obj=requset.FILES.get('one')取到,是一个文件句柄。文件名可以通过file_obj.name取到

      前端核心代码

      注意更改 enctype 参数 !!

    <form action="/upload/" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <p>用户: <input type="text" name='username'></p>
        <p><input type="file" name="one"></p>
        <p><input type="submit" value="提交"></p>
    </form>

      后端核心代码

    def upload(request):
        if request.method=='POST':
            print(request.POST)
            print(request.FILES)
            file_obj=request.FILES.get('one')
            print(file_obj,type(file_obj))             #查看句柄,及其类型。句柄名和句柄.name一样。
            name=file_obj.name
            import os
            from  ORM_BOOK import settings
            path=os.path.join(settings.BASE_DIR,'app01','file',name)
            with open(path,'wb') as f:
                for line in file_obj:         #从文件句柄中,保存的是二进制数据。因为发过来的就是二进制呀
                    f.write(line)
            return HttpResponse('ok')
        return render(request,'upload.html')

      输出:

    <QueryDict: {'csrfmiddlewaretoken': ['HFay06QNV4w9UsUWpJ8i7Te9f8fUEljNieaG7UlF2V5KYvT7COxaMPjVFsAXV6si'], 'username': ['1']}>
    <MultiValueDict: {'one': [<InMemoryUploadedFile: 新建文本文档.txt (text/plain)>]}>
    新建文本文档.txt <class 'django.core.files.uploadedfile.InMemoryUploadedFile'>

    五 ajax 上传数据

      预备知识:

      1 FormData:

        原文博客地址:http://www.cnblogs.com/rubylouvre/archive/2011/04/26/2028827.html

        FF4中增加了一个很有意思的对象,FormData。通常我们提交(使用submit button)时,会把form中的所有表格元素的name与value组成一个queryString,提交到后台。这用jQuery的方法来说,就是serialize。但当我们使用Ajax提交时,这过程就要变成人工的了。因此,FormData对象的出现可以减少我们一些工作量。

        FormData对象添加数据用append('key','value')方法。 key 是input的name值,value是input的框的内容。 value的数据类型可以是字符串,也可以是二进制数据,并没有限定。

    var $formdata=new FormData();
            console.log($formdata,typeof $formdata);
            $formdata.append('username',$("[name='username']").val());
            $formdata.append('one',$("[name='one']")[0].files[0]);

      输出:

    FormData "object"

      2 用jQuery从<input type='file'></input>取到上传的文件内容。

    $("[name='one']")[0].files[0]
    $("[name='one']") jQuery对象
    $("[name='one']")[0] jQuery对象转为DOM对象
    $("[name='one']")[0].files DOM对象的方法
    $("[name='one']")[0].files[0] 取索引值为0,便会取到上传的文件内容。

      3 processData  预处理

        类型:Boolean

        默认值: true。默认情况下,通过data选项传递进来的数据,如果是一个对象(技术上讲只要不是字符串),都会处理转化成一个查询字符串,以配合默认内容类型 "application/x-www-form-urlencoded"。如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。

      4 contentType

      

      前端核心代码,基于ajax,逻辑写在前端

      注意FormData,$formdata.append(), data:$formdata,  $('')[0].files[0],  processData:false

    <body>
    {#<form action="/upload/" method="post" enctype="multipart/form-data">#}
    {#    {% csrf_token %}#}
    {#    <p>用户: <input type="text" name='username'></p>#}
    {#    <p><input type="file" name="one"></p>#}
    {#    <p><input type="submit" value="提交"></p>#}
    {#</form>#}
    <p>用户: <input type="text" name='username'></p>
    <p><input type="file" name="one"></p>
    <p><input type="button" value="提交"></p>
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script src="/static/jquery.cookie.js"></script>
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>
    <script>
        $(':button').click(function () {
            var $formdata=new FormData();
            console.log($formdata,typeof $formdata);
            $formdata.append('username',$("[name='username']").val());
            $formdata.append('one',$("[name='one']")[0].files[0]);
            $.ajax({
                url:'/ajax_upload/',
                type:'post',
                data:$formdata,
                processData:false,
                contentType:false,
                headers:{"X-CSRFToken":$.cookie('csrftoken')},  //第二种发送csrf的方法,用js操作浏览器的cookies
                success:function (data) {
                    console.log(data)
                }
            })
        })
    </script>
    </body>

      后端代码

      基本不用变

    def ajax_upload(request):
        if request.is_ajax():
            print(request.POST)
            print(request.FILES)
            file_obj = request.FILES.get('one')
            print(file_obj, type(file_obj))
            name = file_obj.name
            import os
            from  ORM_BOOK import settings
            path = os.path.join(settings.BASE_DIR, 'app01', 'file', name)
            with open(path, 'wb') as f:
                for line in file_obj:
                    f.write(line)
            return HttpResponse('ok')
        return render(request,'upload.html')

      输出:

    <QueryDict: {'username': ['1111']}>
    [13/Dec/2017 21:15:12] "POST /ajax_upload/ HTTP/1.1" 200 2
    <MultiValueDict: {'one': [<InMemoryUploadedFile: 新建文本文档.txt (text/plain)>]}>
    新建文本文档.txt <class 'django.core.files.uploadedfile.InMemoryUploadedFile'>

    六 自定义auth.user模型

      django自带的user表并不能够满足要求,有时候需要添加age,salary,telephone等字段,怎么办呢?

      完全新建一个独立的表是不行的,我们还需要用django自带的方法。

      有两种思路

      1 新建一个userdetail表,和auth.user表建立一对一的关系

      适用场景:

        很适用于创建第三方扩充包的场景,松耦合,不会破坏之前项目的结构.在自己的django prj下,希望有多重user拥有各自很不相同的字段.或许希望有些用户组合起来一些用户的类型字段,并且希望能在模型层面上解决这些问题.

      2 继承auth.user。推荐这种方式。PS:(模型层,一个模型对应数据库中的一个表。)

      如何实现思路2?

    from django.contrib.auth.models import AbstractUser
    class UserInfo(AbstractUser):

       然后,在settings.py里面添加

      AUTH_USER_MODEL='yourappname.UserInfo(就是你自己写的那个类名)'

        

  • 相关阅读:
    Swift8-枚举Enumerations
    Swift7-闭包
    Swift6-函数
    Swift5-控制流
    Swift4-集合类型
    什么是node.js
    nodejs的安装
    环境变量的认识,,,
    shell是什么,各种shell的初步认识,适用于初学者
    exports和module.exports的区别
  • 原文地址:https://www.cnblogs.com/654321cc/p/8030393.html
Copyright © 2020-2023  润新知