Django学习笔记〇四——做一个稍微正经一点的登录系统
我们在前面学习了如何使用Django来创建一个Web服务,今天我们就做个稍微正经一点的用户登录系统。
首先来看一下需求,我们这个Web服务具备下面几个功能和页面
- 通过/login/地址可以请求用户登录页面/login/
- 通过/user_list/可以显示用户列表
- 用户列表具备用户管理功能,可以实现用户的删除,显示,添加以及修改
- 用户信息存放在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' } }
写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">«</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">»</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">×</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>
在这个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>
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/')
记得ORM修改数据的方法——调用对象的save()方法。
old_user.save()
大概就是这样的过程,记得修改urls.py里的url和函数的对应关系
这样就大体完成了这么一个用户管理Web服务,但是功能上还有很多可以改进的地方:
- user_list需要在登录以后才能访问
- 添加不同的用户管理权限,根据权限可以实现增加、删除或修改用户的功能。
- 等等
我们可以根据后面学的知识进行改进!