在数据库中准备好数据
![image](https://i-blog.csdnimg.cn/blog_migrate/786a2f3ade135d487be864bf07e1f428.png)
三、将MySQL的数据展示到页面(简单认识HTML模板语法 for循环)
- 在Django项目views.py文件中利用ORM模型语法查找所有的数据
| def user_list(request): |
| # 1.获取user表中所有的数据展示到html页面上 |
| user_data = models.UserInfo.objects.filter() # 括号内不填筛选条件等价于查所有 |
| # QuerySet[对象1,对象2] 列表套对象 |
| # 2.利用模版语法传递数据到html页面并完成处理最终返回给浏览器展示 |
| return render(request,'user_list.html',{'user_data':user_data}) |
四、创建用户数据展示HTML页面
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>Title</title> |
| <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script> |
| {# <link rel="stylesheet" href="bootstrap-3.4.1-dist/css/bootstrap.css">#} |
| {# <script src="bootstrap-3.4.1-dist/js/bootstrap.js"></script>#} |
| {% load static %} |
| |
| <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}"> |
| <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script> |
| </head> |
| <body> |
| <div class="container"> |
| <div class="row"> |
| <h1 class="text-center">数据展示页</h1> |
| <div class="col-md-8 col-md-offset-2"> |
| |
| <table class="table table-hover table-striped"> |
| <thead> |
| <tr> |
| <th>ID</th> |
| <th>Name</th> |
| <th>Password</th> |
| <th>Age</th> |
| <th class="text-center">Operation</th> |
| </tr> |
| </thead> |
| <tbody> |
| {% for user_obj in user_data %} # 接收Django提供的模板语法传过来的字典数据 |
| <tr> |
| <td>{{ user_obj.id }}</td> |
| <td>{{ user_obj.name }}</td> |
| <td>{{ user_obj.password }}</td> |
| <td>{{ user_obj.age }}</td> |
| <td class="text-center"> |
| <a href="" class="btn btn-primary btn-xs">编辑</a> |
| <a href="" class="btn btn-danger btn-xs">删除</a> |
| </td> |
| </tr> |
| {% endfor %} |
| </tbody> |
| </table> |
| <a href="/user_login/" class="btn btn-block btn-success">登录用户</a> |
| <a href="/user_register/" class="btn btn-block btn-danger">注册用户</a> |
| |
| </div> |
| </div> |
| |
| </div> |
| </body> |
| </html> |
五、在urls.py路由层中加入视图函数的路径,后面都是如此
![image](https://i-blog.csdnimg.cn/blog_migrate/a81fd844caacd8f001defbbc3f297aa9.png)
六、在浏览器地址栏输入http://127.0.0.1:8010/user_list查看数据展示页面
![image](https://i-blog.csdnimg.cn/blog_migrate/3ce8c1d617b65667c17ecbb59ff8be0d.png)
增----注册功能
- 首先在views.py中写好一个简单的注册视图函数,记得写好后去路由层写一下功能路径
| def user_register(request): |
| #2.根据不同的请求方式做不同的处理 |
| if request.method == 'POST': |
| # 3.获取用户相关数据 |
| username_data = request.POST.get('name') # name age password是前端表单中name属性定义的 |
| age_data = request.POST.get('age') # 这里的数据是前端页面用户数据的数据 |
| password_data = request.POST.get('password') |
| # 继续一些小的判断 |
| if len(username_data) == 0 or len(password_data) == 0: |
| return HttpResponse("用户名或年龄不能为空") |
| user_data = models.UserInfo.objects.filter(name=username_data) # 用户输入的username拿去和数据库中已经存在的用户比较 |
| if user_data: |
| return HttpResponse('用户名已经存在') # 不存在将用模型语法创建一个新用户数据 |
| models.UserInfo.objects.create(name=username_data,age=age_data,password=password_data) |
| # 重定向到数据展示页 |
| return redirect('/user_list/') |
| # 1.先返回一个获取注册新用户数据的html页面 |
| return render(request, 'register.html') |
- 然后写一个注册用户的HTML页面,注意修改表单的请求方式
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>Title</title> |
| <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script> |
| {# <link rel="stylesheet" href="bootstrap-3.4.1-dist/css/bootstrap.css">#} |
| {# <script src="bootstrap-3.4.1-dist/js/bootstrap.js"></script>#} |
| {% load static %} |
| |
| <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}"> |
| <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script> |
| </head> |
| <body> |
| <div class="container"> |
| <div class="row"> |
| <h1 class="text-center">注册用户</h1> |
| <div class="col-md-6 col-md-offset-3"> |
| <form action="" method="POST"> |
| <p>用户名: |
| <input type="text" name="name" class="form-control"> |
| </p> |
| <p>年龄: |
| <input type="text" name="age" class="form-control"> |
| </p> |
| <p>密码: |
| <input type="text" name="password" class="form-control"> |
| </p> |
| <input type="submit" value="注册" class="btn btn-warning btn-block"> |
| </form> |
| |
| </div> |
| |
| </div> |
| </div> |
| |
| </body> |
| </html> |
- 然后去浏览器地址栏输入http://127.0.0.1:8010/register,就可以得到以下页面,当然在数据展示页面点击注册也可以跳到当页面
![image](https://i-blog.csdnimg.cn/blog_migrate/e1fa58f505f8fd033a8b7809bfc93e86.png)
- 在输入框输入新用户,则会看到新用户增加
![image](https://i-blog.csdnimg.cn/blog_migrate/0bc2da5b6be63421f48238517bca44ae.png)
![image](https://i-blog.csdnimg.cn/blog_migrate/10e27a2cd7382950dec7216e5b3ca1c6.png)
ps:注意这里的a是get请求
![image](https://i-blog.csdnimg.cn/blog_migrate/38871e9883fab501b7fb6b7fa312cb27.png)
查----登录功能
- 首先在views.py中写好一个简单的登录视图函数,记得写好后去路由层写一下路径
| def user_login(request): |
| # 2.根据不同的请求方式做不同的处理 |
| if request.method == 'POST': |
| # 3.获取用户相关数据 |
| username_data = request.POST.get('name') # 这里传的是input中name的值 |
| age_data = request.POST.get('age') |
| password_data = request.POST.get('password') |
| # 继续一些小的判断 |
| if len(username_data) == 0 or len(password_data) == 0: |
| return HttpResponse("用户名或年龄不能为空") |
| user_data = models.UserInfo.objects.filter(name=username_data,password=password_data) # 这里是拿出数据库的值(等号前面)和浏览器的值比较 |
| if user_data: |
| return HttpResponse('登录成功') |
| return HttpResponse('该用户不存在') |
| # models.UserInfo.objects.create(name=username_data, age=age_data, password=password_data) |
| # 重定向到数据展示页 |
| # return redirect('/user_list/') |
| # 1.先返回一个获取注册新用户数据的html页面 |
| return render(request, 'login.html') |
- 然后写一个登录用户的HTML页面,注意修改表单的请求方式
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>Title</title> |
| <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script> |
| {# <link rel="stylesheet" href="bootstrap-3.4.1-dist/css/bootstrap.css">#} |
| {# <script src="bootstrap-3.4.1-dist/js/bootstrap.js"></script>#} |
| {% load static %} |
| <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}"> |
| <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script> |
| </head> |
| <body> |
| <div class="container"> |
| <div class="row"> |
| <h1 class="text-center">登录用户</h1> |
| <div class="col-md-6 col-md-offset-3"> |
| <form action="" > |
| <p>用户名: |
| <input type="text" name="name" class="form-control"> |
| </p> |
| <p>密码: |
| <input type="text" name="password" class="form-control"> |
| </p> |
| <input type="submit" value="登录" class="btn btn-danger btn-block"> |
| </form> |
| |
| </div> |
| </div> |
| </div> |
| </body> |
| </html> |
| |
改----编辑功能 (稍微复杂一丢丢)
- 首先在views.py中写好一个简单的编辑视图函数,记得写好后去路由层写一下功能路径
| def user_edit_func(request): |
| # 1.获取用户想要编辑的数据主键值 |
| target_edit_id = request.GET.get('edit_id') |
| # 4.根据不同的请求处理不同的逻辑 |
| if request.method == 'POST': |
| name_data = request.POST.get('name') |
| age_data = request.POST.get('age') |
| if len(name_data) == 0 or len(age_data) == 0: |
| return HttpResponse('用户名或年龄不能为空') |
| models.User.objects.filter(pk=target_edit_id).update(name=name_data, age=age_data) |
| # 5.重定向到数据展示页 |
| return redirect('/user_list/') |
| # 2.根据主键值获取对应的数据 |
| target_edit_obj = models.User.objects.filter(pk=target_edit_id)[0] # QuerySet [对象1,对象2,...] |
| # 3.返回一个编辑数据的页面 并且该页面上需要提前展示出原来的数据 |
| return render(request, 'userEditPage.html', {'target_edit_obj': target_edit_obj}) |
- 然后写一个编辑用户的HTML页面,注意修改表单的请求方式
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>Title</title> |
| <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script> |
| {% load static %} |
| <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}"> |
| <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script> |
| </head> |
| <body> |
| <div class="container"> |
| <div class="row"> |
| <h1 class="text-center">数据编辑页</h1> |
| <div class="col-md-6 col-md-offset-3"> |
| <form action="" method="post"> |
| <p>name: |
| <input type="text" name="name" class="form-control" value="{{ target_edit_obj.name }}"> |
| </p> |
| <p>age: |
| <input type="text" name="password" class="form-control" value="{{ target_edit_obj.password }}"> |
| </p> |
| <input type="submit" value="编辑用户" class="btn btn-primary btn-block"> |
| </form> |
| </div> |
| </div> |
| </div> |
| </body> |
| </html> |
ps:这里需要注意的两个点,也是我第一次写的时候,由于逻辑没有理清,少写了edit_id参数在user_list.html文件中需要用get请求传的参数,所以出现了IndexError: list index out of range错误
![image](https://i-blog.csdnimg.cn/blog_migrate/c9ce940079aceb147aff12472eced14e.png)
- 解决方法
![image](https://i-blog.csdnimg.cn/blog_migrate/50c16d0fe306171b219aa22499ca1f8d.png)
这里注意传点击的id参数 - 在浏览器地址栏搜索编辑页面的时候,不能直接http://127.0.0.1:8010/user_edit/因为没有id,拿不到一个对象,所以列表为空,索引超出了范围
![image](https://i-blog.csdnimg.cn/blog_migrate/b9668ff0fe04ef1d40771ad769d6edc9.png)
- 只需要在地址栏输入http://127.0.0.1:8010/user_edit/?edit_id=2即可,展示页面如下
![image](https://i-blog.csdnimg.cn/blog_migrate/ccc80dfd51b60aaca4ce3f75cc02b409.png)
删----删除功能 (复习前端js的冒泡事件)
- 首先在views.py中写好一个简单的编辑视图函数,记得写好后去路由层写一下功能路径
| def user_delete(request): |
| target_delete_id = request.GET.get('delete_id') |
| models.UserInfo.objects.filter(pk=target_delete_id).delete() |
| return redirect('user_list') |
- 然后去user_list.html页面修改一下删除按钮a便签的href属性,注意修改表单的请求方式,给该便签绑定一个点击事件
| <td class="text-center"> |
| <a href="/user_edit/?edit_id={{ user_obj.pk }}" class="btn btn-primary btn-xs">编辑</a> |
| <a href="/user_delete/?delete_id={{ user_obj.pk }}" class="btn btn-danger btn-xs delBtn">删除</a> |
| </td> |
| |
ps: 二次确认冒泡事件
| <script> |
| $('.delBtn').click(function () { |
| let res = confirm('你确定要删除嘛?') |
| if (res){ |
| {# 如果点击确定 则执行事件冒泡 #} |
| }else{ |
| return false {# 如果点击取消 则阻止事件冒泡 #} |
| } |
| }) |
| </script> |
![image](https://i-blog.csdnimg.cn/blog_migrate/9b9b3df27ce849e6617236fde8a7cb7b.png)
Django请求生命周期流程图
1.Django请求的生命周期的含义
- Django请求生命周期是指:当用户在浏览器上输入URL到用户看到网页的这个时间段内,Django后台所发生的事情。
2.Django请求的生命周期图解及流程
![image](https://i-blog.csdnimg.cn/blog_migrate/bf45d96db8d7056e7ca5a6206c3c3903.png)
![image](https://i-blog.csdnimg.cn/blog_migrate/e95344ccaced5064fcc3213ccb88e371.png)
| 浏览器 |
| 发送请求(HTTP协议) |
| |
| web服务网关接口 |
| 1.请求来的时候解析封装 |
| 响应走的时候打包处理 |
| |
| 2.django默认的wsgiref模块不能承受高并发 最大只有1000左右 |
| 上线之后会替换成uwsgi来增加并发量 |
| |
| 3.WSGI跟wsgiref和uwsgi是什么关系 |
| WSGI是协议 |
| wsgiref和uwsgi是实现该协议的功能模块 |
| |
| django后端 |
| 1.django中间件 |
| 类似于django的保安 门户 |
| |
| 2.urls.py 路由层 |
| 识别路由匹配对应的视图函数 |
| |
| 3.views.py 视图层 |
| 网站整体的业务逻辑 |
| |
| 4.templates文件夹 模版层 |
| 网站所有的html文件 |
| |
| 5.models.py 模型层 |
| ORM |