整体概括请求的走向以及django的核心组成部分
路由匹配的特点就是:只要匹配上了就会立刻结束执行对应的视图函数,并且url方法的第一个参数其实就是一个正则表达式
只要正则表达式能够从用户输入的后缀中匹配到内容就算匹配上了
eg:
正则是test 内容为test 那么就可以匹配出test的文本
正则是test 内容为testadd 那么还可以匹配出test文本
url(r'test', views.test),
url(r'testadd', views.testadd),
def test(request):
return HttpResponse('这是来自test的文本文件')
def testadd(request):
return HttpResponse('这是来自testadd的文本文件')
# 演变过程
url(r'test/', views.test),
url(r'testadd/', views.testadd),
正则增加斜杠,内容还是test
# Django二次追加斜杠机制
首次匹配不上,那么Django就会让浏览器默认加斜杠再次发送请求
test 301 # 重定向
test/ 200
'''
了解:斜杠机制可以取消 但是不推荐
APPEND_SLASH = False
'''
正则test/ 内容为abcasdjstest/ 还可以匹配test
所以我就需要在正则最前面加上一个上尖号来限制
'''可以解决上面这种随意乱写的问题'''
正则是^test/ 内容是test/abc/edf/acd/ 还可以匹配出文本test/
所以我们就可以在正则最后面加上$来限制最后
'''这个就解决了后面可以乱写的问题'''
# 由于第一个参数是正则,所以当项目特别大的时候,对应关系特别多的时候要小心是否出现路由顶替的现象
# 扩展小知识
我们可以 定制一个主页面,用户不携带后缀是可以直接访问
url(r'^$', views.home),
def home(request):
return render(request, 'home文件夹.html')
还可以设计一个尾页,就是当用户输入没有对应关系的后缀,直接返回
url(r'.*', views.error)
"""
无名分组:
路由匹配成功之后就会调用视图函数默认情况下会自动给视图函数传递一个request未知参数
test(request)
当路由匹配中使用括号对正则表达式进行了分组,那么在调用视图函数的时候,会将括号内匹配到的内容当做位置参数传给视图函数
test(request, 括号里面内正则表达式匹配到的内容)
url(r'^test/([0-9]{4})/$', views.test),
def test(request, aaa):
print('aaa:', aaa)
return HttpResponse('这是来自test的文本文件')
"""
url(r'^test/(\d+)/$', views.test), # 可以拿到任意的参数
# 有名分组:
"""
给括号内的正则表达式器起别名之后,匹配成功则会将括号里面匹配到的内容按照关键字参数传递给视图函数
testadd(request,user_id=括号内正则表达式匹配到的内容)
url(r'testadd/(?P<user_id>[0-9]{4})$', views.testadd),
def testadd(request,user_id):
print('user_id:',user_id)
return HttpResponse('这是来自testadd的文本文件')
"""
# 无名有名分组可以混用
url(r'^test/(\d+)/(?P<user_id>[0-9]{4})/$', views.test),
def test(request, aaa, user_id):
print('user_id:', user_id)
print('aaa:', aaa)
return HttpResponse('这是来自test的文本文件')
# 提示缺少一个参数aaa,但是无名已经给了,所以这俩不能一块用
报错: test() missing 1 required positional argument: 'aaa'
# 单个重复使用 都可以
url(r'^test/(\d+)/(\d+)/$', views.test)
url(r'^test/(?P<a>\d+)/(?P<b>\d+)',views.testadd)
"""
a标签的herf可以写网址的全称,也可以写后缀
href='https://www.4399.com'
href='/login/' # 自动补全当前服务的ip和port
相当于:
href='127.0.0.1:8000/login/'
"""
1、页面上很多a标签链接了其他路由
2、路由匹配表达式出现了变化、html页面上的地址全部失效
# 反向解析
通过反向解析可以获取到一个结果,这个结果可以直接访问到一个路由
步骤1: 给对应关系起别名
url(r'^func098/',views.func,name='func_view')
步骤2:使用反向解析获取结果
前端:
{% url 'func_view' %} # func098/ 结果可以访问路由
后端:
from django.shortcuts import reverse
print(reverse('func_view')) # func098 / 结果可以访问路由
# 无名分组方向解析
步骤1、 给对应关系起别名
url(r'^func666/(\d+)/', views.func, name='func_view'),
步骤2、使用方向解析获取结果
# 无法明确括号内正则表达式的内容,需要人为的指定
前端:
{% url 'func_view' 123 %} # func666/123/
后端:
from django.shortcuts import reverse
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/
"""
无名有名反向解析的手动传值,这个值在实际工作中到底是什么
一般情况下这个值可以是数据的主键值、页面的代码、区域的编号
"""
"""
当一个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'))
1、不同的应用使用了相同的别名 ,那么方向解析是否自动识别
index_view app01/index/
index_view app02/index/
# app01>>>: /app02/index
# app02>>>: /app02/index
2、系统不会自动给你添加应用前缀,如何解决反向解析
方式一: 名称空间
总路由添加名称空间
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' %}
app02>>>: /app02/index
app01>>>: /app01/index
方式2:只需要确保反向解析的别名在整个项目中不重复就可以
可以在别名的前面加上应用名的前缀
url(r'^index/',views.index,name='app01_index_view')
url(r'^index/',views.index,name='app02_index_view')