• Django学习笔记〇四——做一个稍微正经一点的登录系统


    我们在前面学习了如何使用Django来创建一个Web服务,今天我们就做个稍微正经一点的用户登录系统。

    需    求

     首先来看一下需求,我们这个Web服务具备下面几个功能和页面

    1. 通过/login/地址可以请求用户登录页面/login/
    2. 通过/user_list/可以显示用户列表
    3. 用户列表具备用户管理功能,可以实现用户的删除,显示,添加以及修改
    4. 用户信息存放在MySQL数据库中。
    分    析

    需求分析

    • 创建django项目及loginAPP
    • 创建数据库UserInfo,
    • 通过Django创建UserInfo里的table(user)
    • 多个html页面可以使用以前学习Bootstrap框架时的多个代码。
    • 11
    • 22

    准备

    在写代码以前,我们需要先一系列的准备工作

    创建项目,项目名我们定为login

    创建APP,应用名为loginapp

    创建数据库文件——UserInfo

    修改配置文件

    添加应用——在INSTALLED_APPS列表最后添加应用名(还有注释小下面那个列表的第四项)

    指定数据库

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST':'127.0.0.1',
            'PORT':3306,
            'NAME': 'UserInfo',
            'USER':'root',
            'PASSWORD':'123456'
        }
    }
    View Code

    写ORM对应的数据类并通过命令行创建table

    class User(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(null = False,max_length=10)
        password = models.CharField(null=False,max_length=10)
    数据表

    创建好表以后在MySQL里的UserInfo里应该有下面的表

     能到现在这一步就说明我们前面的配置应该都是没问题的,下面我们针对不同的URL对应的函数来讲,第一步应该是127.0.0.1:8000/login/对应的登录页面

    登录页面

    html文件

    登录的页面的html文件就用了以前Bootstrap框架时的一个现成的页面,但是稍微修改了一下,添加了登录异常状态的提示

    Views.py内的函数login()

    login的函数大概是下面的思路

    def login(request):
        err_msg = ''
        if request.method == 'POST':
            name_login = request.POST.get('name')
            pwd_login = request.POST.get('pwd')
            user_inDB = models.User.objects.filter(name=name_login).first()if not user_inDB:
                err_msg='无此用户'
            elif user_inDB.password == pwd_login:
                return redirect('/user_list/')
            else:
                err_msg='密码错误'
    
        return render(request,'login.html',{'error_message':err_msg})

    login的页面我们在两种情况下需要调用:

    • 直接访问 
    • 登陆失败

    而login的访问是由POST和GET两种方式的,在登陆提交form的时候我们选择的方式是POST,所以我们把这段功能放在了一个函数中。并且后面的各种功能(添加、修改用户)我们都用这种思路写。

    这里使用了ORM获取数据的方式——filter(),相当于select * from user where name=...,通过输入的name从数据库中获取到用户取user——inDB的信息,我们这里用filter不用get的原因就是可能有用户不存在的情况,如果用filter的话可以返回一个空的值,而用get的话就会直接报错。user_inDB对应的是User类的一个对象,其中有一个属性就是pwd,把这个pwd和输入的密码进行比较,如果相同就直接跳转到user_list页面内。否则直接修改错误信息的内容后重新跳转login页面,方式为GET。

    用户列表界面

    如果登录成功,就直接跳转到这个用户列表界面

    HTML文件

    这个html文件还是使用前期学习Bootstract架构时候的一个现成的页面,稍微修改了一下

    <!DOCTYPE html>
    <!-- saved from url=(0042)https://v3.bootcss.com/examples/dashboard/ -->
    <html lang="zh-CN">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
        <meta name="description" content="">
        <meta name="author" content="">
    
        <title>用户资料</title>
        <!-- Bootstrap core CSS -->
        <link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    
        <!--页面使用的自定义CSS-->
        <link href="/static/dashboard.css" rel="stylesheet">
    </head>
    
    <body>
    
    
    <div class="container-fluid">
        <div class="row">
            <div class="col-sm-3 col-md-2 sidebar">
                <ul class="nav nav-sidebar">
                    <li class="active"><a href="/user_list/">用户列表 <span class="sr-only">(current)</span></a>
                    </li>
                    <li><a href="/add_user/">新增</a></li>
    
                </ul>   
    
                </ul> -->
            </div>
            <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
                <h1 class="page-header">管理后台
                    <small>用户信息</small>
                </h1>
    
                <!--面板 开始-->
                <div class="panel panel-primary">
                    <div class="panel-heading">用户信息</div>
                    <div class="panel-body">
                        <div class="row my-table-toolbar">
                            <div class="col-md-4">
                                <div class="input-group">
                                    <input type="text" class="form-control" placeholder="Search for...">
                                    <span class="input-group-btn"><button class="btn btn-default" type="button">Go!</button></span>
                                </div><!-- /input-group -->
                            </div>
                            <div class="col-md-1 pull-right">
                                <button class="btn btn-success" data-toggle="modal" data-target="#myModal" >添加</button>
                            </div>
                        </div>
                        <table class="table table-striped table-bordered">
                            <thead>
                            <tr>
                                <th>id</th>
                                <th>name</th>
                                <th>pwd</th>
                                <th>操作</th>
                            </tr>
                            </thead>
                            <tbody>
    
                {% for user in user_list %}
                <tr>
                    <td>{{user.id}}</td>
                    <td>{{user.name}}</td>
                    <td>{{user.password}}</td>
                    <td>
                        <a class="btn btn-info" href="/edit_user/?id={{user.id}}">编辑</a>
                        <a class="btn btn-danger" href="/delete_user/?id={{user.id}}">删除</a>
                    </td>
                    {% endfor %}
                </tr>
    
                         </tbody>
                        </table>
    
                        <div class="pull-right">
                            <nav aria-label="Page navigation">
                                <ul class="pagination">
                                    <li>
                                        <a href="#" aria-label="Previous">
                                            <span aria-hidden="true">&laquo;</span>
                                        </a>
                                    </li>
                                    <li><a href="#">1</a></li>
                                    <li><a href="#">2</a></li>
                                    <li><a href="#">3</a></li>
                                    <li><a href="#">4</a></li>
                                    <li><a href="#">5</a></li>
                                    <li>
                                        <a href="#" aria-label="Next">
                                            <span aria-hidden="true">&raquo;</span>
                                        </a>
                                    </li>
                                </ul>
                            </nav>
                        </div>
                    </div>
                    <!--面板body 结束-->
                </div>
                <!--面板 结束-->
            </div>
        </div>
    </div>
    
    <!--模态框 开始-->
    <div id="myModal" class="modal fade" tabindex="-1" role="dialog">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
                    </button>
                    <h4 class="modal-title">模态框</h4>
                </div>
                <div class="modal-body">
                    <form class="form-horizontal" method="POST" action="/add_user/">
                        <div class="form-group">
                            <label for="inputEmail3" class="col-sm-2 control-label">Email</label>
                            <div class="col-sm-10">
                                <input type="email" class="form-control" id="inputEmail3" placeholder="Email" name="name">
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="inputPassword3" class="col-sm-2 control-label">Password</label>
                            <div class="col-sm-10">
                                <input type="password" class="form-control" id="inputPassword3" placeholder="Password" name="pwd">
                            </div>
                        </div>
                        <!-- <a class="btn btn-primary" href="/add_user/" method='POST'>添加123</a> -->
                        <input type="submit"  value="添加">
                    </form>
                    <p>{{add_error}}</p>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                    <!-- <button type="button" class="btn btn-primary">保存</button> -->
                   
    
                </div>
            </div><!-- /.modal-content -->
        </div><!-- /.modal-dialog -->
    </div><!-- /.modal -->
    <!--模态框 结束-->
    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>
    
    
    </body>
    </html>
    user_list.html

    在这个html文件中包含了一模态的弹框,用了实现新用户的创建。并且在里面我们做了一个循环

                {% for user in user_list %}
                <tr>
                    <td>{{user.id}}</td>
                    <td>{{user.name}}</td>
                    <td>{{user.password}}</td>
                    <td>
                        <a class="btn btn-info" href="/edit_user/?id={{user.id}}">编辑</a>
                        <a class="btn btn-danger" href="/delete_user/?id={{user.id}}">删除</a>
                    </td>
                    {% endfor %}
                </tr>

    通过Python代码,我们可以实现user_list里面的字符串的替换。

    views.user_list()函数

     这个函数比较简单,主要就是通过ORM框架来获取所有的用户数据。但是这里省略了一个很重要的部分——数据的分页。因为数据量比较小,就省略了这个功能。

    def user_list(request):
        all_user = models.User.objects.all()
        return render (request,'user_list.html',{'user_list':all_user})

    这里还用到了一些类似前面提到的Jinja2库(实现模板字符串替换功能)的语法,用all_user这个变量里的值去替换html文件中的user_list这个变量,然后通过上面的for循环把数据填在表格内。

    用户添加

     用户添加我没有重新写html文件,刚好套用了user_list里的那个模态对话框。对话框中有两个input可以用来输入新用户的信息,然后form指定了要提交的地址和方式

    <form class="form-horizontal" method="POST" action="/add_user/">

    而在/add_user/指向的函数中我们直接获取到用户信息,然后创建新用户

    def add_user(request):
        if request.method == 'POST':
            new_name = request.POST.get('name')
            new_pwd = request.POST.get('pwd')
            models.User.objects.create(name=new_name,password=new_pwd)
            return redirect('/user_list/')

    由于在html文件中我们已经做了用户名的验证,这里就不在实现用户名是否有效的验证,其实还可以加上检查用户名是否存在的效果,方法比较简单这里就不再讲了。

    用户删除

     用户删除是通过获取用户的id来操作ORM直接删除数据。用户的id就是在usesr_list的html文件中添加了按钮的时候直接获取的用户id

    <a class="btn btn-danger" href="/delete_user/?id={{user.id}}">删除</a>

    注意这里我们使用的是一个a标签,再通过css样式把他改成按钮的显示效果。那么在点击的时候会直接跳转到/delete_user/的链接,这个链接我们只实现了 用户的删除效果,执行完毕后再返回user_list页面因为我们没有指定具体的method,那么就默认是

    GET。我们还在url后指定了参数:/delete_user/?id=1,那么就可以直接用get的方式获取到带的参数,也就是要删除的用户对应的ID。

    def del_user(request):
        del_id = request.GET.get('id')
        del_user = models.User.objects.filter(id=del_id)
        del_user.delete()
        return redirect('/user_list/')

    最后就是删除数据的用法——先获取数据ORM对象,然后直接调用delet()方法。

    用户修改

     用户修改的思路和删除差不多,都是先获取到指定的用户对象。这个时候的请求方式是GET,然后把这个对象里的值放在input输入框内,在修改以后提交新数据以后请求方式就成了POST,把新的数据进行修改就可以了。

    HTML文件

    这个HTML文件比价简单,就放了三个input输入框还有一个submit提交按钮。有一个输入框我们用来显示被修改的数据的ID,但是由于ID不能被修改,我们把这个input直接设置为不可见。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <form action="" method="POST">
            <p><input type="text" name="id" value="{{user.id}}" style="display: none;">
            name:<input type="text" name="name" id="" value="{{user.name}}"></p>
            <p>
                pwd:<input type="text" name="pwd" id="" value="{{user.password}}">
            </p>
            <p>
                <input type="submit" value="修改">
            </p>    
        </form>
    </body>
    </html>
    edit_user.html

    views.edit_user()

    函数分为两部分,首先是获取要修改的数据对应的ID并依据ID把原数据显示出来,其次就是把修改过的数据POST给数据库保存。

    def edit_user(request):
        if request.method == 'GET':
            get_id = request.GET.get('id')
            user = models.User.objects.get(id=get_id)
            return render(request,'edit_user.html',{'user':user})
        if request.method == 'POST':
            edit_id = request.POST.get('id')
            old_user = models.User.objects.get(id=edit_id)
            new_name = request.POST.get('name')
            new_pwd = request.POST.get('pwd')
            old_user.name = new_name
            old_user.password = new_pwd
            old_user.save()
            return redirect('/user_list/')
    views.edit_user()

    记得ORM修改数据的方法——调用对象的save()方法。

    old_user.save()
    最终

    大概就是这样的过程,记得修改urls.py里的url和函数的对应关系

      这样就大体完成了这么一个用户管理Web服务,但是功能上还有很多可以改进的地方:

    1. user_list需要在登录以后才能访问
    2. 添加不同的用户管理权限,根据权限可以实现增加、删除或修改用户的功能。
    3. 等等

    我们可以根据后面学的知识进行改进!

  • 相关阅读:
    CSAPP阅读笔记-struct, union, 数据对齐-来自第三章3.9的笔记-P183-P191
    CSAPP阅读笔记-数组分配与访问-来自第三章3.8的笔记-P176-P183
    深入理解静态方法和实例化方法的区别
    通俗讲解静态方法和实例方法的区别
    ArcGis中的类模型图目录
    C++ Primer(第四版) 课后习题6.8 统计空格制表符换行的数目
    C++ Primer(第四版) 课后习题4.30
    string类sizeof大小
    C++ Primer(第四版) 课后习题4.18
    C++ Primer(第四版) 课后习题3.14 vector单词转大写
  • 原文地址:https://www.cnblogs.com/yinsedeyinse/p/12379925.html
Copyright © 2020-2023  润新知