django请求生命周期流程图 路由层中的路由匹配 无名分组 有名分组 反向解析 名称空间 路由分发
作者:互联网
概要
-
作业讲解(注册登录功能)
-
django请求生命周期流程图
-
路由层相关知识点
路由匹配 无名分组 有名分组 反向解析 名称空间 路由分发
内容
1.django中的注册登录功能作业讲解
1.因为我们需要使用django自带的数据库 所以我们先去模型层models.py文件中先创建一张数据库表 记得写完数据库表后记得写那两句迁移命令
ps:第一次使用pycharm连接sqlite3也需要先下载驱动
2.编写注册、登录功能
先在路由层urls.py文件中存储关系 照着已写的urls格式依葫芦画瓢
from app01 import views
# 注册功能
url(r'^reg/',views.reg)
在路由层存储完关系直接去视图层views.py中去编写核心逻辑代码
def reg(request):
return render(request,'reg.html') 注意需要先创建一个reg.html文件 然后在settings配置中去添加静态配置 然后创建一个静态文件static 用来存储第三方模块bootstrap 然后第三方静态文件可能无法拖进到pycharm文件栏中 原因是C盘不支持 可以采用CV操作
前期提交post请求时发现出现403 需要在配置文件中注释一行
# 注册核心逻辑代码
def reg(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
confirm_pwd = request.POST.get('confirm_password')
# 1.先判断两次密码是否一致
if not password == confirm_pwd:
return HttpResponse('两次密码不一致')
# 2.判断用户名是否已存在
is_user = models.UserInfo.objects.filter(name=username)
if is_user:
return HttpResponse('当前用户已存在')
# 3.写入数据库 models.UserInfo.objects.create(name=username,pwd=password )
# return HttpResponse(f'{username}注册成功')
# 4.直接跳转到登录页面(利用的是三把斧中的第三把 redirect 有重定的功能 ):后面还可以实现 注册之后自动跳转登录
return redirect('/login/')
return render(request,'reg.html')
# 登录核心逻辑代码
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
is_user = models.UserInfo.objects.filter(name=username).first() # 除了直接用first()后还可以使用索引取值也是可以的
# filter结果是列表嵌套对象
if not is_user:
return HttpResponse('用户名不存在')
if str(is_user.pwd) == password: # 获取到的用户输入是字符串 数据库字段是整型
return HttpResponse('登录成功')
return HttpResponse('密码错误')
return render(request,'login.html')
2.django请求生命周期流程图
整体概括请求request的走向以及django的核心组成部分
后期django的学习就是按照图上的部分 一小块一小块的详细的去学习
周期流程图参考截图
3.路由层之路由匹配
路由匹配的特点是:只要匹配上了就会立即结束执行对应的视图函数
并且url方法的第一个参数其实是一个正则表达式 只要正则表达式能够从用户输入的后缀中匹配到内容就算匹配上了
大白话:在urls文件中第一个参数其实就是正则表达式 路由层上的正则表达式能够与用户输入的后缀内容中找到相同的内容就能执行视图函数即是路由匹配 以用户输入后缀内容为大原则
eg: 正则表达式是test 内容是test
正则表达式是test 内容是testadd
在针对这个正则表达式中test 都能在用户在输入test与testadd都能与正则找到相同的内容 所以都会执行test后面的视图函数 而testadd后面的视图函数就不会执行 所以针对这个问题我们应该如何处理呢???
解决措施是:我们在用户输入的test后缀和正则表达式后面都加上一个斜杠 这样我们发现用户在输入test/与testadd/都能匹配执行各自的视图函数
演变过程
正则表达式是test/加上了一个斜杆 我们在浏览器上输入的内容是test 那么首次输入test内容无法执行视图函数 那么第一次不能匹配后 是不是都无法执行了呢?
答案:肯定是不是的 因为django本身存在一个二次自动追加斜杠的机制
# django二次追加斜杠机制
首次如果匹配不上 那么django还会自动让浏览器默认加斜杠再次发送请求
第一次 test 301 不能匹配
第二次 test/ django会自动默认加一个斜杠 然后再次发送请求 然后就会显示200可以了
"""
了解:斜杆机制可以取消 但是不推荐取消
APPEND_SLASH = False"""
正则是test/ 内容是abcdefgtest/ 那么也是可以匹配出文本test/ 针对路由前面可以随意乱写的问题 可以在正则的最前面加上正则表达式里面的^上箭头来限制
正则是^test/ 内容是test/abc/def/acd/ 那么可以匹配出文本test/ 为了解决路由后面可以随意乱写的问题 可以在正则表达的最后加上$来限制
# 由于第一个参数是正则 所以当项目特别大 对应关系特别多的时候要格外注意是否会出现路由顶替的现象
小扩展:
可以定制一个主页面 用户不携带后缀可以直接访问(掌握)
url(r'^$',views.home)
也可以定义一个尾页面 用户输入一个没有对应关系的直接返回(了解)
url(r'.*',views.error)
4.无名有名分组
url(r'^test/([0-9]{4})/$,views.test)
"""
路由匹配成功之后就会调用视图函数默认情况下回自动给视图函数def(request,位置参数)传递一个位置参数
如果路由匹配中使用括号对正则表达式进行了分组 那么在调用视图函数时 会将正则表达式中分组的内容作为一个位置参数传递给视图函数def中
上述这个特性django称之为'无名分组'
"""
url(r'^testadd/(?P<user_id>[0-9]{4})$',views.testadd)
"""
给括号内的正则表达式起别名user_id之后 匹配成功则会将括号内匹配到的内容按照关键字参数传递给视图函数def中
def(request,正则表达式中起别名中的关键字参数[0-9]{4})"""上述这个特性在django中称之为'有名分组'
# 两者是否可以混合使用
url(r'^test/(\d+)/(?P<user_id>[0-9]{4})/$',views.testadd) # 验证两者是不可以混合使用的
无名有名分组不能混合使用!!! 单个是可以重复使用的
url(r'^test/(\d+)/$',views.testadd) # 可以
url(r'^test/(?P<a>\d+)/(?P<b>\d+)',views.testadd) # 可以
5.反向解析
"""
我们都知道在前端中 a标签中的href既可以写网址的全程 也可以写网址的后缀
比如 href= 'https://www.baidu.com'
href='/login/' # 因为写了后缀 在调用时它自自己会把当前服务的IP与port端口自动补全
href= '127.0.0.1:8000/login/'
"""
1.假设页面上有很多a标签连接了其他路由
2.当路由匹配表达式发生了变化 我们发现html页面上的地址会出现全部失效的结果
为了处理这样的情况 我们引出了反向解析的解决办法
# 反向解析
通过反向解析我们可以获得到一个结果 然后我们通过该结果可以访问到一个路由
大白话:就是说我们通过反向解析可以得到一个结果 然后我们用这个结果找到url中那对关系 不管那对关系中的正则表达式怎么变化 都不影响这个结果找到url中的这对关系
步骤1:给对应关系起别名
url(r'^func666/',views.func,name='func_view' (起了一个别名)) #
步骤2:使用反向解析获取结果 适用于前后端
前端:{% url 'func_' %} # func666/ 通过反向解析出来的这个结果'func666/'可以访问到路由
后端:
from django.shortcuts import reverse
reverse('func_view') # func666/ 通过反向解析出来的结果'func666'可以访问到路由
# 有名分组反向解析
步骤1:给对应关系起别名
url(r'^func666/(\d+)/',views.func,name='func_view')
步骤2:使用反向解析获取结果
"""因为在有名分组中 我们不知道这个位置参数的内容到底是什么 可以是123 、234、1、3、4等随便的数 所以系统也不知道我们需要什么数据 所以系统就会报错 所以需要我们人为去指定具体的数据值
前端:
{% url 'func_view' 123 %} # func666/123/
后端:
from django.shortcuts import revserse
reverse('func_view',args=(666,)) # func666/666/"""
# 有名分组反向解析
步骤1:给对应关系起别名
url(r'^func666/(?P<id>\d+)/',views.func,name='func_view')
步骤2:使用反向解析获取结果
"""无法明确括号内正则表达式的内容 需要人为指定"""
前端: {% url 'func_view' 123 %} # func666/123/
{% url 'func_view' id=123 %} # func666/123/
后端:
from django.shortcuts import reverse
reverse('func_view',args=(666,)) # func666/666/
reverse('func_view',kwargs={'id':1}) # func666/1/
"""
疑问:无名有名反向解析中的手动传值 这个值在实际工作中到底可以是什么
一般情况下这个值可以是数据的主键值、页面的页码、区域的编号等
6.路由分发
"""
如果一个django项目特别庞大 里面有很多应用 每个应用下有很多对应关系
那么django自带的路由层里面的代码就会非常非常的多 如何优化???
根据应用的不同拆分到不同的应用中
django支持每个应用都可以有自己独立的
路由层、模板层、静态文件、视图层(默认)、模型层(默认)
上述特性能够让django在分组开发上更加的方便、快捷
所有人都可以在应用中开发完整的项目功能
最后汇总到一个空的django项目中 然后通过路由分发整合所有人的应用
"""
1.创建多个应用 并去配置文件中注册
INSTALLED_APPS = [
'app01',
'app02'
]
2.在多个应用中编写相同的路由
urlpatterns = [
url(r'^index/',views.index111)
]
urlpatterns = [
url(r'^index/',views.index)
]
3.路由分发
总路由
from django.conf.urls import url, include
from app01 import urls as app01_urls
from app02 import urls as app02_urls
url(r'^app01/',include(app01_urls)),
url(r'^app02/',include(app02_urls))
"""总路由只负责分发 不负责视图函数对应"""
上述代码还可以简写
from django.conf.urls import url, include
url(r'^app01/',include('app01.urls')),
url(r'^app02/',include('app02.urls'))
7、名称空间
1.不同的应用使用了相同的别名 那么反向解析是否自动识别
index_view app01/index/
index_view app02/index/
2.验证发现默认情况下是不会自动识别应用前缀的 如何解决反向解析问题
方式1:名称空间
总路由添加名称空间
url(r'^app01/',include('app01.urls',namespace='app01')),
url(r'^app02/',include('app02.urls',namespace='app02'))
应用反向解析自动提示
reverse('app01:index_view')
reverse('app02:index_view')
{% url 'app01:index_view' %}
{% url 'app02:index_view' %}
方式2:只需要确保反向解析的别名在整个项目中不重复即可!!!
可以在别名的前面加上应用名的前缀
url(r'^index/',views.index,name='app01_index_view')
url(r'^index/',views.index,name='app02_index_view')
"""
名称空间其实是可有可无的知识 但是在实际工作中还是有不少程序员喜欢使用
标签:views,url,层中,django,分组,test,路由,view 来源: https://www.cnblogs.com/wht488232/p/16364772.html