08 url之路由控制

编辑本博客

yuan先生博客

简单路由配置

urls.py 配置路由

正则路由匹配:

类似re正则,无需像path那样路径必须一样。匹配从上至下,能匹配到即刻返回,不会再朝下匹配

from django.urls import path,re_path
  • ^以什么开头
  • $以什么结尾
from django.urls import re_path
from app01 import views
urlpatterns = [
    re_path(r'^special_case_2003/$',views.special_case_2003)
]
View Code
  • ([0-9]){4},只要在url匹配中进行分组后,会自动将分组内容传递给位置参数,所以处理函数必须有相应位置参数
    re_path(r'^special_case/([0-9]{4})/$',views.special_case_2003)
        #可匹配special_case/2001/,special_case/2002/,special_case/2003/,special_case/2004/等类似url
    View Code
    def year_archive(request,year):
        return HttpResponse("year:%s" % year)
    View Code

  • 在正则中有多个分组,则需多个位置参数
    re_path(r'^archive/([0-9]{4})/([0-9]{2})$',views.math_archive),
    View Code
    def math_archive(request,year,math):
        return HttpResponse("year:%s年%s月" % (year,math))
    View Code

注意:

  • 若要从url中捕获一个值,只需要在周围放置一对圆括号
  • 不需要添加一个前置反斜杠,因为每个url都有
  • 每个正则前面的'r'可选,但建议放置,告诉python为原始字符,任何字符都无需转义

HttpResponse

自己构造响应体

from django.shortcuts import render,HttpResponse
def special_case_2003(request):
    #直接给浏览器返回一个h1标签
    return HttpResponse("<h1>special_case_2003</h1>")
View Code 

有名分组

即对url正则中捕获的参数进行命名,避免顺序混乱。即通过关键字参数进行传参。

?P<m>
re_path(r'^archive/(?P<y>[0-9]{4})/(?P<m>[0-9]{2})$',views.math_archive),

在视图函数中接收参数时,位置颠倒无所谓

def math_archive(request,m,y):
    return HttpResponse("year:%s年%s月" % (y,m))
View Code

路由分发

将各个app的路由分开定义,,通过include方法进行指定,由全局路由进行分发,分发到应用上

在应用下面新建一个urls.py文件

在本urls文件中,单独定义路由

from django.urls import re_path,path
from app01 import views
urlpatterns = [
    path('timer/', views.timer),
    re_path(r'^special_case_2003/$',views.special_case_2003),
    re_path(r'^archive/([0-9]{4})/$',views.year_archive),
    re_path(r'^archive/(?P<y>[0-9]{4})/(?P<m>[0-9]{2})$',views.math_archive),
]
View Code

在全局urls文件中,通过include方法对其接入

from django.urls import path,re_path,include
urlpatterns = [
    #分发路由
    re_path(r"app01/",include("app01.urls"))
]
View Code

浏览器中访问新的路径

路由反向解析

  • request.GET获取所有get方法的数据
  • request.POST获取所有post方法的数据

 在urls中定义path的时候给取别名

path('logins/', views.login,name="login")

在html模板中通过固定方式获取动态的url地址,别名相同即可

<form action="{% url 'login' %}" method="post">
    <input type="text" name="name" placeholder="用户名">
    <input type="password" name="pwd" placeholder="密码">
    <input type="submit" value="登录">
</form>
View Code

render的时候会自动查找同名的url,避免path中路径修改后需要到html中同步修改

视图函数中使用反向解析

路由中添加名称空间后,在url中使用反向解析一定要加上名称空间前缀,冒号分割

与访问的路由无关系

首先导入反向解析模块

from django.urls import reverse

给urlpath起别名

re_path(r'^special_case_2003/$',views.special_case_2003,name="s_c_2003")

在视图函数中即可使用

def special_case_2003(request):
    url=reverse("s_c_2003")
    print(url)

反向解析带组的域名,需要添加相应参数

url中添加了分组

re_path(r'^archive/([0-9]{4})/$',views.year_archive,name="y")

视图函数中访问会出现报错

def special_case_2003(request):
    url2=reverse("y")
    print(url2)

此时需要给符合正则的参数

def special_case_2003(request):
    url1=reverse("s_c_2003")
    print(url1)
    url2=reverse("y",args=(2008,))
    print(url2)
    return HttpResponse("<h1>special_case_2003</h1>")
View Code

路由之名称空间

路由中添加名称空间后,在url中使用反向解析一定要加上名称空间前缀,冒号分割

不同的app中可能存在同名的路径别名,这样就会出现冲突

如,在app01中定义一个name='index'的别名

re_path("index/",views.index,name="index")

如,在app02中同样定义一个name='index'的别名

re_path("index/",views.index,name="index")

此时,在视图函数中反向解析则会出问题,在不同的应用中反向解析出来的域名是一样的

我们在全局include应用urls时,添加名称空间,元祖的方式传入

re_path(r"^app01/",include(("app01.urls",'app01'))),
re_path(r"^app02/",include(("app02.urls",'app02')))

在视图函数中反向解析的时候,添加名称空间和别名即可解决

app01中

def index(request):
    url=reverse('app01:index')
    print(url)
    return HttpResponse("app01 index")

app02中

def index(request):
    url = reverse('app02:index')
    print(url)
    return HttpResponse("<h2>app02 index</h2>")

在不同的应用中反向解析同名路径别名

路由控制path方法 

在url中匹配成功的值都是字符串,容易导致数据类型错误

def math_archive(request,m,y):
    print(type(y),type(m))

相同的规则可能在不同的url中出现,修改起来比较麻烦

Django2.0中出现path函数,可解决上面问题

  • 使用尖括号从url中捕获值
  • 捕获值中可以包含一个类型转换器
  • 无需添加前置反斜杠

支持的转换器

  • str:匹配除了路径分隔符(/)以外的所有非空字符,默认形式
  • int:匹配整型
  • slug:匹配字面,数字,下划线组成的字符串
  • uuid:匹配格式化的uuid如ddddd-33333-fffffff
  • path:匹配非空字符串,包含路径分隔符
path("index2/<int:year>"),

在视图函数中查看year参数类型

def index(request,year):
    print(type(year))
    return HttpResponse("app01 index")

int类型

自定义转换器

class MonConvert:
    regex="[0-9]{2}"
    def to_python(self,value):
        return int(value)
    def to_rul(self,value):
        return '%04d' % value

在urls中注册自定义转换器

from django.urls import register_converter
register_converter(MonConvert,'mm')

在视图函数中打印类型

def path_month(request,month):
    print(type(month))
    return HttpResponse("app01.path_month")
View Code

 

posted @ 2018-06-27 12:19  丫丫625202  阅读(201)  评论(0编辑  收藏  举报