Django 路由配置 (二)

django处理请求

Django 和其他 Web 框架的 Http 处理的流程大致相同,web服务器软件或者模块(wsgiref)会把http 发送的请求封装成了一个 Request 对象, Django 处理一个 Request 的过程首先是通过中间件,然后再通过默认的 URL 方式进行的. 我们可以在中间件(middleware)这个地方把所有 Request 拦截住,用我们自己的方式完成处理以后直接返回 Response。
Django 路由配置 (二)_第1张图片

路由的过程:

1.当发起请求时,首先会根据项目目录下的根路由URLconf(urls.py)下查找路由规则urlpatterns。

2.urlpatterns变量定义为列表,元素是django. urls.path()实例 或django.urls.re_path()实例,这两种对象定义了url与视图的对应关系。

3.django会按照顺序匹配每个url模式,并匹配到第一个模式后停止匹配,且django 将导入并调用对应的视图。

4.如果没有匹配的模式,或在过程中引发了异常,django将调用错误视图。

路由模块

根路由:主路由,项目目录下的urls.py,会包含其他的子路由。
子路由:各应用模块下的urls.py。

path()返回的对象就是一条路由规则,其可接收的参数:

path(route,view,kwargs=None,name=None)
# route: str格式,路由规则
# view: 视图
# kwargs: 需要传递的参数
# name: 路由的名字

继续以上篇为例:
在应用模块projects目录下的views.py文件中编写如下代码:

from django.http import HttpResponse

def index(request):
    return HttpResponse('首页')


def pro(request):
    return HttpResponse('项目')

创建子路由,在应用projects目录下创建urls.py文件

from django.urls import path
from projects import views

urlpatterns = [
    path('', views.index),
    path('pro/', views.pro)
]

在项目demo1目录urls.py中添加如下路由:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', include('project.urls')),
    path('', include('project.urls'))
]

当捕获url中的参数时需使用<>来定义变量名,如下:

from django.urls import path
from projects import views

urlpatterns = [
    path('', views.index),
    path('pro//', views.pro)
]

视图中则需要接收这捕获到的值作为形参:

from django.http import HttpResponse

def index(request):
    return HttpResponse('首页')


def pro(request,pid):
    return HttpResponse(f'项目id为{pid}')

在这里插入图片描述
路径转换器
如果需要声明url中需捕获的参数类型,可以通过路径转换器来设置:
Django内置下面的路径转换器:

str:默认的,匹配除路径分隔符 " / " 以外的任何非空字符串

from django.urls import path
from projects import views

urlpatterns = [
    path('', views.index),
    path('pro//', views.pro) #默认为str
]

在这里插入图片描述

int:匹配0和正整数,返回一个int类型

from django.urls import path
from projects import views

urlpatterns = [
    path('', views.index),
    path('pro//', views.pro)
]

在这里插入图片描述

slug:匹配任何ASCII字母以及连接符和下划线,比如a_b-c

from django.urls import path
from projects import views

urlpatterns = [
    path('', views.index),
    path('pro//', views.pro)
]

在这里插入图片描述

uuid:匹配格式化的uuid。

from django.urls import path
from projects import views

urlpatterns = [
    path('', views.index),
    path('pro//', views.pro)
]

在这里插入图片描述

path:匹配任何非空字符串,可以包含路径分隔符 " / ",允许匹配完成的url路径。

from django.urls import path
from projects import views

urlpatterns = [
    path('', views.index),
    path('pro//', views.pro)
]

在这里插入图片描述
re_path()
返回一个对象,表示一条正则匹配规则的url匹配模式,和path的不同为route部分包含了正则表达式。

path(route,view,kwargs=None,name=None)

当进行匹配,从正则表达式中捕获的组会被传递到视图中。如果组是命名的,则作为命名的参数,否则作为位置参数,值以字符串的形式传递,不做任何的类型转换。
有命名的分组(?P< name>pattern),name是组的名称,pattern是正则表达式.

from django.urls import path,re_path
from . import views

urlpatterns = [
    path('', views.index),
    re_path(r'^pro/(?P\d{4})/(?P[1-9]|1[0-2])/$', views.pro)
]
from django.http import HttpResponse

def pro(request, year, month):
    return HttpResponse(f"出生年月为:{year}-{month}")

在这里插入图片描述

url命名

动态获取对应视图的url。
django.shortcuts.reverse函数,接收url的名字,然后反向解析出对应的绝对路径。

from django.urls import path, re_path
from . import views

urlpatterns = [
    path('', views.index),
    path('detail//', views.detail, name='detail'),
    path('pro_list/', views.pro_list, name='prolist'),
    re_path(r'^pro/(?P\d{4})/(?P[1-9]|1[0-2])/$', views.pro)
]
from django.http import HttpResponse
from django.shortcuts import reverse

def detail(request, pid):
    return HttpResponse('项目id为{}'.format(pid))

def pro_list(request):
	print(reverse('detail', args=(2,)))
    html = '''
     项目1
    '''.format(reverse('detail', args=(2,)))
    return HttpResponse(html)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

app_name

当一个项目下有多个应用时,难免会给url定义相同的名字,而如果不区分name的话,则获取不到正确的绝对路径,如下:

应用project下的urls.py

from django.urls import path
from project import views
urlpatterns = [
    path('project/', views.index, name='index')
]

view代码:

from django.http import HttpResponse
from django.shortcuts import reverse

def index(request):
    return HttpResponse('应用1首页{}'.format(reverse('index')))

应用project1下的urls.py

from django.urls import path
from project1 import views
urlpatterns = [
    path('project1/', views.index, name='index')
]

view代码:

from django.http import HttpResponse
from django.shortcuts import reverse

def index(request):
    return HttpResponse('应用2首页{}'.format(reverse('index')))

此时两个不通的项目通过url名字获取到的路由地址都为:
在这里插入图片描述
在这里插入图片描述
而通过app_name可以来区分不通应用中相同名字的路由,只需在子路由中添加变量app_name来声明,在reverse中来指定路由名字,如下:
应用project下的urls.py

from django.urls import path
from project import views

app_name = 'project'
urlpatterns = [
    path('project/', views.index, name='index')
]

view代码:

from django.http import HttpResponse
from django.shortcuts import reverse

def index(request):
    return HttpResponse('应用1首页{}'.format(reverse('project:index')))

应用project1下的urls.py

from django.urls import path
from project1 import views

app_name = 'project1'
urlpatterns = [
    path('project1/', views.index, name='index')
]

view代码:

from django.http import HttpResponse
from django.shortcuts import reverse

def index(request):
    return HttpResponse('应用2首页{}'.format(reverse('project1:index')))

结果如下:
在这里插入图片描述
在这里插入图片描述

你可能感兴趣的:(Django,django,python,中间件)