django初级请求周期与初级路由
- 作业讲解
- django请求生命周期
- 路由系统
路由匹配
无名分组
有名分组
反向解析
路由分发
名称空间
作业讲解
1.配置文件
修改TEMPLATES文件下DIRS路径os.path.join(BASEDIR,'templaces')
注销MIDDLEWARE路径下 #'django.middleware.csrf.CsrfViewMiddleware'
修改数据库配置
'ENGINE':'django.db.backends.mysql',
'NAME':'mysql',
'HOST':'127.0.0.1',
'PORT':3306,
'USER':'root',
'PASSWORD':'',
'CHARSET':'utf8'
创建静态文件夹static
配置静态文件路径
SATICFILES_DIRS =[os.path.join(BASE_DIR,'static')]
使用终端创建一个库绑
import pymysql
pymysql.install-as_MYSQLab()
2.模型类中创建表
class User(models.Model):
name = models.CharField(max_length=32)
pwd =models.IntegerField()
age = models.IntegerField
3.urls路由层中创建对应关系
path('/home/',view.home)
4.views中创建功能函数
5.连接数据库读取数据库中所有数据组织成列表对象
6.创建html页面利用小白三板斧render将列表对象传入html页面
在页面中循环遍历给前端浏览器传入对像之后可以在html页面中使用
{{% for user_obj in data_obj%}}
{{% endfor% }}
通过对像点的方法可以直接点出具体数据值
并在标签中创建两个a连接 提供用户跳转到其他页面
可以在连接网址后面是有?变量=对象点方式将当前点击的对象数据通过前端传给GET方法
具体按流程
#数据编辑
1.通过html页面按钮a连接进入编辑页面
GET方法获取a连接后携带的数据值
通过数据值筛选出数据库中对应的数据
通过浏览器编辑打包数据传入后段后端拿到数据后对筛选出来的用户进行数据更新 跟新好数据 通过重定项返回数据展示页面至浏览器中
#数据添加
1点击添加数据页面进入添加页面 编辑信息传入后端
2后端拿到数据后利用name 字段对数据库中数据进行比对如果存在则直接返回文本前端页面提示用户已存在
3如果不存在 将数据添加到数据库中更新数据库
4重定项返回数据库数据到前端页面
#删除用户
1html删除标签中通过?字段=值的方式将数据传入前端页面
2前端页面拿到数据后点击之后会通过GET请求将数据传入端
3后端利用该数据进行数据库筛选 用delete方法直接删除
4重定项返回用户展示数据页面
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.0/jquery.js"></script>
{# <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">#}
{# <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>#}
{% load static %} <!--静态解析static文件-->
<link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1 class="text-center">数据展示</h1>
<a href="/useradd/" class="btn-info btn-xs">添加用户</a>
<table class="table table-hover table-striped ">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>pwd</th>
<th>age</th>
<th>operation</th>
</tr>
</thead>
<tbody>
{% for data_obj in data_queryset %} <!--动态创建tr行数-->
<tr>
<td>{{ data_obj.id }}</td>
<td>{{ data_obj.name }}</td>
<td>{{ data_obj.pwd }}</td>
<td>{{ data_obj.age }}</td>
<td><a href="/useredit/?id={{ data_obj.id }}" class="btn-success btn-xs">编辑</a>
<a href="/del_user/?id={{ data_obj.id }}" class="btn-danger btn-xs">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
数据页面展示
def userlist(request):
data_queryset = models.Userinfo.objects.filter() # 括号内不写参数= 没有过滤条件
return render(request, 'userlist.html', {'data_queryset': data_queryset}) # 返回html页面,将所有对象传到html页面进行处理
添加数据
def useradd(request):
if request.method == 'POST': # 获取POST传的所有数据通过get的方式取值
username = request.POST.get('username')
pwd = request.POST.get('password')
age = request.POST.get('age')
# 查询数据库中是否有该名字
user_obj = models.Userinfo.objects.filter(name=username) # 第一个参数是数据库中的字段=获取到的字段
if user_obj:
return HttpResponse('用户已存在无法添加')
# 写入数据库
models.Userinfo.objects.create(name=username, pwd=pwd, age=age)
return redirect('/userlist/')
# 返回添加用户页面
return render(request, 'useradd.html')
修改数据
def useredit(request):
print('来自post',request.POST)
print('来自get',request.GET,)
edit_id = request.GET.get('id') # GET获取前端页面数据
if request.method == 'POST': # 判断是否是POST请求
edit_name = request.POST.get('username')
edit_pwd = request.POST.get('password')
edit_age = request.POST.get('age')
models.Userinfo.objects.filter(id=edit_id).update(name=edit_name, pwd=edit_pwd, age=edit_age) # 数据库更新
return redirect('/userlist/') # 返回数据展示页面
edit_obj = models.Userinfo.objects.filter(id=edit_id).first()
return render(request, 'useredit.html', {'edit_obj': edit_obj}) # 返回数据修改页面和将对象传入html文件
删除用户
def del_user(request):
delete_id = request.GET.get('id') # 获取用户id
print(request.POST)
print(request.GET)
models.Userinfo.objects.filter(id=delete_id).delete() # 筛选之后删除即可
return redirect('/userlist/') # 返回数据展示
django请求生命周期流程图

路由匹配
path(网址后缀,函数名)
一旦网址后缀匹配上了就会自动执行后面的函数并结束整个路由匹配
1.路由结尾写杠
默认情况下不会写斜杠,django会做二次处理
第一此匹配不上会让浏览器加斜杠再次请求
django配置可以指定是否自动添加斜杠
APPEND_SLASH = False
2.path转换器
当网址后缀不固定的时候可以使用转换器来匹配
'int':InConverter()
'path':PathConverter()
'slug':SlugConverter()
'str':StringConverter()
'unid':UUIDConverter()
path('func/<int:year>',views.func
转换器匹配到的内容会当作视图函数关键字参数传入
转换器有几个名字那么视图函数就有几个形参必须对应
def func(request,year):
pass
'''使用了转换器之后输入网址的时候用了几个转换器那么网址就需要输入几个字段'''
当后缀不固定的时候可使用转换器来匹配
3.re_path正则匹配
re_path(正则表达式,函数名)
一旦网址后缀的正则能匹配上内容就自动执行函数
并结束匹配
匹配路由网址中只要出现同样的文本无论多长都能匹配成功
re_path('^home/$',view.home)
使用正则文本匹配的时候加^使匹配再网址的开头位置才能匹配成功$可以限制结尾只能是/
4.正则匹配无名分组
re_path('^home/(\d+)/',views.home)\d+表示无限数字
正则表达式匹配到的内容会当作视图函数的位置参数传入
5.正则匹配之有名分组
re_path('^test/(?P<year>\d+)/(?P<others>.*?)/', views.test) 起别名之后在视图函数中接收的参数需要与别名一致
正则表达式匹配到的内容会当做视图函数的关键字参数传递给视图函数
6.django版本区别
在django1.11中 只支持正则匹配 并且方法是 url()
django2,3,4中 path() re_path() 等价于 url()
反向解析
页面上写死很多路由一旦修改路由相关链接失效
为防止出现问题需使用反向解析
"""
反向解析:返回一个结果 该结果可以访问到对应的路由
"""
1.路由对应关系起别名
path('register/', views.reg, name='reg_view')
2.使用反向解析语法
html页面
{% url 'reg_view' %}
后端
from django.shortcuts import reverse
reverse('reg_view')
ps:反向解析的操作三个方法都一样path() re_path() url()
无名有名反向解析
*反向解析使用针对redirect
path('reg/<str:info>/', views.reg, name='reg_view')
当路由中有不确定的匹配因素 反向解析的时候需要人为给出一个具体的值
reverse('reg_view', args=('jason',))
{% url 'reg_view' 'jason' %}
ps:反向解析的操作三个方法都一样path() re_path() url()
路由分发
django中的应用都可以有自己独立的
urls.py templates文件夹 static文件夹
能够让基于django开发的多个应用完全独立 便于小组开发
总路由
path('app01/', include('app01.urls')),
path('app02/', include('app02.urls')),
子路由
path('after/', views.after) # app01
path('after/', views.after) # app02
"""
当项目特别大 应用特别多的时候 可以使用路由分发 非常方便!!!
"""
名称空间
有路由分发场景下多个应用在涉及到反向解析别名冲突的时候无法正常解析
解决方式1
名称空间
namespace
path('app01/', include(('app01.urls', 'app01'), namespace='app01'))
path('app01/', include(('app01.urls', 'app02'), namespace='app02'))
解决方式2
别名不冲突即可
"""
保证django项目下没有重复的别名即可
"""

浙公网安备 33010602011771号