• Django基础二之URL路由系统


    一 URL配置

    **基本格式 **

    from django.conf.urls import url
    #循环urlpatterns,找到对应的函数执行,匹配上一个路径就找到对应的函数执行,就不再往下循环了,并给函数传一个参数request,就是请求信息的所有内容
    urlpatterns = [
         url(正则表达式, views视图函数,参数,别名),
    ]
    

    参数说明 

    • 正则表达式:一个正则表达式字符串
    • views视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
    • 参数:可选的要传递给视图函数的默认参数(字典形式)
    • 别名:一个可选的name参数

    二 正则表达式详解

    基本配置

    from django.conf.urls import url
    
    from . import views
    
    urlpatterns = [
        url(r'^articles/2003/$', views.special_case_2003), #思考:如果用户想看2004、2005、2006....等,你要写一堆的url吗,是不是在articles后面写一个正则表达式/d{4}/就行啦,网址里面输入127.0.0.1:8000/articles/1999/试一下看看
        url(r'^articles/([0-9]{4})/$', views.year_archive), 
        url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), #思考,如果你想拿到用户输入的什么年份,并通过这个年份去数据库里面匹配对应年份的文章,你怎么办?怎么获取用户输入的年份啊,分组/(d{4})/,一个小括号搞定
        url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
    ]
    

      views.py中视图函数的写法:

    第一个参数必须是request,后面跟的三个参数是对应着上面分组正则匹配的每个参数的
    def article_detail(request,year,month,day):
        return HttpResponse(year+month+day)
    

    注意事项

    1. urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。
    2. 若要从URL中捕获一个值,只需要在它周围放置一对圆括号(分组匹配)。
    3. 不需要添加一个前导的反斜杠(也就是写在正则最前面的那个/),因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
    4. 每个正则表达式前面的'r' 是可选的但是建议加上。
    5. ^articles& 以什么结尾,以什么开头,严格限制路径

    补充说明

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

    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})/([0-9]{2})/$', views.month_archive)。而更高级的用法是,使用分组命名正则表达式组来捕获URL中的值并以关键字参数的形式传递给视图。

    在Python的正则表达式中,分组命名正则表达式组的语法是(?P<name>pattern),其中name是组的名称,pattern是要匹配的模式。

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

    这个实现与前面的示例完全相同,只有一个细微的差别:捕获的值作为关键字参数而不是位置参数传递给视图函数。

    views.month_archive(request, year="2017", month="12"),year和month的位置可以换,没所谓了,因为是按照名字来取数据的
    

    URLconf匹配的位置**

        URLconf 在请求的URL 上查找,将它当做一个普通的Python 字符串。不包括GET和POST参数以及域名。

        例如,http://www.example.com/myapp/ 请求中,URLconf 将查找myapp/。

        在http://www.example.com/myapp/?page=3 请求中,URLconf 仍将查找myapp/

        URLconf 不检查请求的方法。换句话讲,所有的请求方法 —— 同一个URL的POSTGETHEAD等等 —— 都将路由到相同的函数。

    捕获的参数永远都是字符串

    每个在URLconf中捕获的参数都作为一个普通的Python字符串传递给视图,无论正则表达式使用的是什么匹配方式。例如,下面这行URLconf 中:

    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    

      传递到视图函数views.year_archive() 中的year 参数永远是一个字符串类型。

    四 路由分发及命名空间

    django里面的app可以有自己的static文件,templates文件夹,urls.py(******)   
    
        项目名下面的urls.py不再做路由与视图函数对应关系
        而是做一个中转站  只负责将请求分发到不同的app中 
        然后在app的urls.py完成路由与视图函数的对应关系
    

    比如说我有十个人要开发,每个人都不需要沟通,只用开发自己的那个app就好了,你的老板只需要建立一个空的Django项目,把你们每个人的app拿过来,在settings里面注册一下,然后在urls里面路由分发一下就好了。

    这时候比如说你的app01和app02 都有一个index函数:

    from django.conf.urls import url,include
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^app01/',include('app01.urls')),
        url(r'^app02/',include('app02.urls'))
    ]
    

    接下来你只需要在浏览器里面请求 “127.0.0.1:8080/app01/index/"访问到app01里面的index了,改成app02就能访问到app02的index。

    别忘了多个app时,在settings.py中设置

    但这时候就出了一个问题,两个app,是不是都可以给自己的index起别名!

    那么反向解析的时候会怎么样,Django能不能帮你自动识别出来呢?

    结果是不行,他还没有智能到区分到那个应用上,所以有两种方式来解决:

    ### 方式一、名称空间**
    
    from app01 import urls as app01_urls
    from app02 import urls as app02_urls
    from django.conf.urls import url,include
    urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^app01/',include(app01 _urls,namespace='app01')),
    url(r'^app02/',include(app02_urls,namespace='app02'))
    ]
    

    现在就相当于给他们搞了个名称空间,我们在解析的时候:

    这是app01的index

    def index(request):
        print(reverse('app01:index'))
        return HttpResponse('hahaa')
    

    app02的也一样。

    方式二、约定俗成

    通常情况下,起别名的时候,前面可以加上你的应用名,因为应用是不可能会重名的,所以只需要在你起别名的时候,在前面加上应用名就好了。

    比如在你app01的urls里面

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^index/',views.index,name='app01_index'),
    ]
    

    这个时候就永远也不会重名了,除非有程序员不遵守这种规则。

    五 url反向解析

    咱们简单来说就是可以给我们的URL匹配规则起个名字,一个URL匹配模式起一个名字。

      这样我们以后就不需要写死URL代码了,只需要通过名字来调用当前的URL。

      举个简单的例子:

    url(r'^home', views.home, name='home'),  # 给我的url匹配模式起名(别名)为 home,别名不需要改,路径你就可以随便改了,别的地方使用这个路径,就用别名来搞
    url(r'^index/(d*)', views.index, name='index'),  # 给我的url匹配模式起名为index
    

     在模板里面可以这样引用:

    {% url 'home' %}  #模板渲染的时候,被django解析成了这个名字对应的那个url,这个过程叫做反向解析
    

    在views函数中可以这样引用

    from django.urls import reverse   #导如reverse方法
    
    reverse("index", args=("2018", ))
    

    在views函数中可以这样引用

    from django.urls import reverse
    
    reverse("index", args=("2018", ))
    
  • 相关阅读:
    PHP笔试题
    找工作的几种方式
    ThinkPHP3.2.3学习笔记5---模板(一)
    PHP7新特性
    了解Web Uploader
    什么是云购网
    使用PDO操作数据库的好处
    MySQL与MongoDB的区别
    显示和编辑注解
    自定义验证逻辑
  • 原文地址:https://www.cnblogs.com/zzsy/p/12309771.html
Copyright © 2020-2023  润新知