• Django框架-Django路由(urls)系统


    Django的路由系统

    Django 1.1版本 URLConf官方文档

    URL配置(URLconf)就像Django所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表。

    我们就是以这种方式告诉Django,遇到哪个URL的时候,要对应执行哪个函数。

    一、URLconf配置

    基本格式:

    from  django.conf.urls  import url
    
    urlpatterns = [
    
        url(正则表达式,views视图,参数,别名),
    ]
    参数说明:
      正则表达式:一个正则表达式字符串
      view视图:一个可调用对象,通常为一个视图函数
      参数:可选的要传递给视图函数的默认参数【字典新式】
      别名:一个可选的name参数,当动态改路劲时需用到

    示例:

    from django.conf.urls import url
    from . import views
    
    urlpatterns = [
        url(r'^articles/2003/$', views.special_case_2003),
        url(r'^articles/([0-9]{4})/$', views.year_archive),
        url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
        url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
    ]

    请求的例子:
    /articles/2005/3/ 不匹配任何url模式,因为列表中的第三个模式要求月份应该是两个数字。
    /articles/2005/ 将匹配列表中的第一个模式不是第二个,因为模式按顺序匹配,第一个会首先测试是否匹配。
    /articles/2005/03/ 请求将匹配列表中的第三个模式,django将调用函数views.month_archive(request,'2005','03')

     注意:

    Django2.0版本中的路由系统是下面的写法(官方文档):

    from django.urls import path,re_path
    
    urlpatterns = [
        path('articles/2003/', views.special_case_2003),
        path('articles/<int:year>/', views.year_archive),
        path('articles/<int:year>/<int:month>/', views.month_archive),
        path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
    ]
    注:2.0版本中re_path和1.11版本的url用法一样。

    正则表达式详解:

    1、urlPartterns中元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续,谁在上面,就先匹配,会覆盖下面的。

    2、若要从url中捕获一个值【即可以从url中获取参数】,只需要在它周围放置一对圆括号(分组匹配)。

    3、不需要添加一个前导的反斜杠,因为每个url都有,例如,应该是^active/而不是^/active/。

    4、每个正则表达式前面的r‘’是可选的但建议加上,以防特殊字符未转义。

    补充说明

    # 是否开启URL访问地址后面不为/跳转至带有/的路径的配置项
    APPEND_SLASH=True

    Django settings.py配置文件中默认没有 APPEND_SLASH 这个参数,但 Django 默认这个参数为 APPEND_SLASH = True。 其作用就是自动在网址结尾加'/'。

    其效果就是:

    我们定义了urls.py:

    from django.conf.urls import url
    from app01 import views
    
    urlpatterns = [
        url(r'^blog/$', views.blog),
    ]

    访问 http://www.example.com/blog 时,默认将网址自动转换为 http://www.example/com/blog/ 。

    如果在settings.py中设置了 APPEND_SLASH=False,此时我们再请求 http://www.example.com/blog 时就会提示找不到页面。

    二、无名分组和命名分组

    无名分组:就是正则匹配分组,圆括号包起来的部分,未指定别名,匹配完全后,将url中的匹配的括号包起来的值,以位置参数传递给视图函数

    url(r'^articles/([0-9]{4})/$', views.year_archive),
    
    # 上面([0-9]{4})就是无名分组,匹配4位数字,当前端url中如输入
    http://127.0.0.1:8000/2016/ 时,2016就是匹配的值,django将会将2016以位置参数传给后面的视图函数 def  year_archive(request,2016):pass  以用于业务逻辑

    命名分组:就是给分组指定一个别名,python的正则分组命名语法为(?P<name>pattern),其中name是组的命名,pattern是匹配的模式,将url中匹配的部分以,关键字参数传递给视图函数。

    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    
    # 如浏览器中输入:http:// 127.0.0.1:8000/articles/2016/,
    django 会将匹配的2016以关键字分方法传递给视图函数供其调用, def year_archive(request, year = ’2016‘):pass

    小结:

    1、urlconf匹配时,将url当成一个普通的字符串,不考虑请求方法,ip或域名,仅匹配http://www.baidu.com/index/?wd=python 着色部分。

    2、捕获的参数永远都是字符串 ,如上面传递给视图函数 views.year_archive()中的year的参数永远是一个字符串,而不是一个数字类型。

    3、视图函数中可以指定默认值

    # urls.py中
    from django.conf.urls import url
    
    from . import views
    
    urlpatterns = [
        url(r'^blog/$', views.page),
        url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
    ]
    
    # views.py中,可以为num指定默认值
    def page(request, num="1"):
        pass

    在上面的例子中,两个URL模式指向相同的view - views.page - 但是第一个模式并没有从URL中捕获任何东西。

    如果第一个模式匹配上了,page()函数将使用其默认参数num=“1”,如果第二个模式匹配,page()将使用正则表达式捕获到的num值。

    4、urlconf可以传递额外的参数给视图函数

    URLconfs 具有一个钩子,让你传递一个Python 字典作为额外的参数传递给视图函数。

    django.conf.urls.url() 可以接收一个可选的第三个参数,它是一个字典,表示想要传递给视图函数的额外关键字参数。

    例如:

    from django.conf.urls import url
    from . import views
    
    urlpatterns = [
        url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
    ]

    在这个例子中,对于/blog/2005/请求,Django 将调用views.year_archive(request, year='2005', foo='bar')。
    当传递额外参数的字典中的参数URL中捕获值的命名关键字参数同名时,函数调用时将使用的是字典中的参数,而不是URL中捕获的参数。

    三、Url分发

    当多个应用在一个项目里时,需要用到url分发,各app管理自己的url

    例如:app01、app02

    1、分别在app01和app02下创建自己的urls.py【各应用下与views.py同级目录中创建】

    2、分别配置app的urls.py

    app01
    
    from django.conf.urls import url # 导入管理url的模块
    
    from app01 import views # 导入应用的的views
    
    urlpatterns = [ url(r'^home/[0-9]{4}/[0-9]{2}/$' ,views.app01_home)]
    
    app02 类似

    3、在全局urls.py文件中导入app01及app02的urls

    1、from django.conf.urls import include
    
    2、在urlpatterns中写入
    
    url(r'^app01/' ,include('app01.urls')),
    
    url(r'^app02/', include('app02.urls'))

    注:此时相当于app01是一级目录,而app自己的url相当于二级目录,当访问时先到全局urls后到应用的urls

    相当于进行字符串拼接

    如:http://www.baidu.com/app01/home  会先找到app01,再去对应app下的urls中找home的url

    四、命名Url和Url反向解析 

    官方:Django 提供一个办法是让URL 映射是URL 设计唯一的地方。你填充你的URLconf,然后可以双向使用它:

    • 根据用户/浏览器发起的URL 请求,它调用正确的Django 视图,并从URL 中提取它的参数需要的值。
    • 根据Django 视图的标识和将要传递给它的参数的值,获取与之关联的URL。

    第一种方式就是,正向的,我们在浏览器种输入地址,服务器到urls去匹配,然后执行对应的视图函数。

    第二种方式就是,反向解析url,反向url匹配,反向url查询或简单的url反查,如我们业务处理中redirect跳转等。

    本质为urls.py中的url匹配规则设置别名

    作用:解决当需要更新页面或视图函数中的url时,无需再一个个去遍历修改,只需要再urlsconf中即urls.py中修改,视图和模板就会自动更新url

    常规

    url(r'show_class/', views.show_class, name='class_list'),

    无名分组

    url(r'^home/([0-9]{4})/([0-9]{2})/$',views.login ,name='home')

    有名分组

    url(r'^home/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$',views.login ,name='home')

    在views中使用

    from django.shortcuts import reverse # 导入反向解析模块

    常规

    def test(request):
    
    return redirect(reverse('class_list'))

    无名分组

    return redirect(reverse('home' , args=('1988','09')))
    
    上面会字符串拼接成:home/1988/09/

    命名分组

    return redirect(reverse("home", kwargs={"year":2018}))

    在模板html中使用

    语法:{% url 路径设置的别名 %}

    常规

    {% url 'class_list' %}

    无名分组

    {% url 'home' '2018' '09' %}

    有名分组

    {% url 'home' '2018' '09' %}
    
    {% url 'home' month='09' year='2018' %}

    命名空间模式

    当多个app的url设置的别名相同时,容易出现异常报错,在全局urls里后面的覆盖前面的,故有下面两个方案解决

    1、在url命名前加上应用的名字 如 name = 'app_name.路径别名'

    2、在全局urls.py中导入app01时,为url也进行命名 namespace='别名,一般为应用的名字'

    from django.conf.urls import url, include

    url( r'app01/ ',include('app01.urls', namespace= 'app01'))

    3、在app的views.py视图函数使用

    from django.shorcuts import reverse

    def
    test(request) return redirect(reverse('app01:home', ))

    4、在模板中使用

    {% url 'app01:home' %}

    注:如果app在全局的url指定了namesapce,那么单个app的应用url就必须也指定name,不然无法使用!!!

      

  • 相关阅读:
    团队项目心得(一)
    《effective c++》读书笔记(上)
    前端进度报告(2018.5.17)
    DeltaFish 校园物资共享平台 第五次小组会议
    项目--用户调研
    DeltaFish 校园物资共享平台 第四次小组会议
    DeltaFish 校园物资共享平台 第三次小组会议
    创建校园二手交易及资源共享平台的问卷调查
    项目平台统一(前后端IDE、代码风格)
    DeltaFish 校园物资共享平台 第二次小组会议
  • 原文地址:https://www.cnblogs.com/sunxiuwen/p/9643812.html
Copyright © 2020-2023  润新知