django 之 路由系统

模式:url -----> 函数

静态路由:

  指的是写死的url,对应的某个视图函数的操作!要想看到相对应的模版,还需要手动在浏览器的地址栏中敲,前提是你知道这个url,否则就呵呵了!

  基础中写的全是静态路由: /login/ -> def login

动态路由:

  利用正则去匹配,同时兼顾seo权重的问题(爬虫爬取规则)
  - seo权重:是搜素引擎匹配的规则
  - 注意点:get传参虽然可以实现功能,但是传值的参数会经常变动,同时这种方式的权重太低,并且安全性不高,数据在地址栏上直接就能显示!
      get传参标志---> ? 为避免这种问题,尽量少用。
  - URL 实质还是正则表达式,网页地址栏敲地址,实质上还是在与正则做匹配!

避免get传值:

  1. 正则匹配urls页面,此时视图函数就需要再写一个形参,用于接收这个固定url后的值。
    - 按位(顺序)传参

    /add-user/(\w+)/ -> def add_user(request,a1) --- a1会接收(\w+)匹配传递的值
    /add-user/(\w+)/(\w+)/ -> def add_user(request,a1,a2) --a1 是接收第一个,a2是接收第二个
    - 此处一定要注意:匹配给视图函数传值;函数在接收的时候,是严格按照顺序接收的!

    - 指定传参,按照名称传递(不再按照顺序)

      /add-user/(?P<a1>\w+)/ -> def add_user(request,a1)
      /add-user/(?P<a1>\w+)/(?P<a2>\w+)/ -> def add_user(request,a1,a2)

  注意:
    在路由系统中:按顺序传参和指定名称传参不能混用,要不然视图函数无法完成匹配接收。就是万能的(*args,**kwargs)也无法相对应接收!所以书写的时候一定要统一用法。顺序传参由:args接收;按照指定名称传参由kwargs接收!
  PS:
    终止符$:
      - 如果页面没有终止符,那么网址之后就可以任意的写urls或是多个urls拼接在一起,这样也可以访问页面。

      但是我们不希望是有这种情况发生,毕竟不同的urls对应着不同的页面,所以urls之后写上终止符,只有写上固定的URL才能访问,其他的都不行。
      ^edit$
    伪静态:

      - 在urls之后加上.html,伪装成固定的静态网站(特点:速度快!)权重最高!
        url(r'^edit/(\w+).html$', views.edit),


  2. 路由分发:(应用于多个app开发)
    - 首先明确一点:多个app代表多个不同的业务。
    - 用于解决多部门间协同开发同一框架上不同的业务功能模块的方法。

    这种机制是让每个业务线操作写路由关系urls的时候互不干预,避免同时操作一个文件导致url重复的问题!
  - 路由分发配置
    1、app文件中复制一份urls.py文件,py文件中用于书写当前app的对应关系
    2、在项目主目录下mysite的urls.py文件中导入include

    from django.conf.urls import include
    配置:
    url(r'^app文件名/', include('app文件名.urls')), #注意:全是字符串格式
    示例:
    urls.py
    url(r'^app01/', include('app01.urls')),

    app01.urls.py
    url(r'^index.html$', views.index),

  执行原理:
    把路由匹配分成了两级,先在项目中的urls.py中匹配路由,路由urls指向对应的app文件,然后会在去app文件下的urls.py匹配相对应的url。

  3、默认路由:(常用于访问出错,或是路由不匹配的情况下返回的固定信息)
    - 所有路由都没有匹配成功,再执行的路由关系,返回固定的提示或是固定的某个页面

示例:
    from app01 import views
    from django.shortcuts import HttpResponse

    def default(request):
        return HttpResponse('哥们,走错了。。')
    url(r'^',default ),#返回固定的提示!

    views.py 
        def index(request):
            return render(request,"index.html")
        url(r'^', views.index), #返回默认页面
            

  4、命名:用于根据名字反向生成url
    (最大特点:可以通过名字反向生成url,用以应对 书写或是存储 复杂或是长的 路径)

    - 给urls.py文件中的对应关系,命名 name = "xxx" 
    /add-user/(\d+)/ -> def add_user(request,a1) name=n1

  根据名称可以反向生成URL
    1. 在Python代码中 :通过request 和参数反生成url

from django.urls import reverse
    def add_user(request,a1)
        v = reverse('n1',
            args=xxx, #对应顺序传参
            kwargs={'a1':1111} #对应按位传参 
            #为url传值,生成新的url,想获取什么url就获取什么url 两种方式二选一
        )
        print(v)
        return render(request,"index.html")

浏览器地址栏:127.0.0.1:8000/index/123
后台拿到的v: index/1111    

    2. 在模版页面中,也可以根据名称反生成url(视图函数中不用传值,也不用返回值)

- 没有参数的情况:
    视图函数中:
        def login(request) 
            return reder(request,"login.html")
    模版文件中:	
        url(r'^login/', views.login,name='m1')
        {% url "m1" %}
- 有参数,传值:	
    视图函数中:
        def login(request,a1(*args)) 
            return reder(request,"login.html")
    模版文件中:	
        url(r'^login/', views.login,name='m1')
        {% url "m1" 值 %} #按照顺序传值 单个值
        {% url "m1" 值1 值2 %} #按照顺序传值 多值

#写值的时候,一定要注意空格!   

 5、URL 路由分发中 关于 namespace

  我们在写路由分发的时候都是用include("app名字.urls") 实现。我们查看include源码发现,这个方法最后 return [],appname,namespace,[]第一个列表代表所有的url地址,
namespace 和url中的name一样指定这个include,所以,当我们做路由分发的时候,可以指定namespace的值也可以不写,传入的值可以是个列表,也可以是个字符串类型的文件地址(本质是获取这个文件内的url列表)。
  我们知道,可以通过name反解出详细的url地址,那如果有namespace怎么办?起始Django内部给了我们解决办法:reverse("namespace:name"),反解的时候将namespace与name通过冒号拼接;如果是有多层的include,及多个namespace(可以不写),

当我们进行反解url的时候,就需要从最外层的namespace通过冒号(:),一直拼接到name,如下:reverse("namespace1:namespace2:..:name")。

namespace 作用是url间的分割,name命名的隔离。其最主要的一点是:在反向生成url的时候,避免name相同的情况下出现混淆;支持嵌套,只要是namespace不同即可。

url(r'^app01/', include([
        url(r'^login/', include([
            url(r'^log/', views.login, name='login'),
        ],namespace='n2')),
        url(r'^logout/', views.logout, name='logout'),
        url(r'^test/', views.test),
    ], namespace='n1')),
    
    url(r'^app02/', include([
        url(r'^login/', include([
            url(r'^log/', views.login, name='login'),
        ],namespace='n2')),
        url(r'^logout/', views.logout, name='logout'),
        url(r'^test/', views.test),
    ], namespace='n2'))
]

from django.urls import reverse
def test(request):
    # 反向生成login和logout的url
    print(reverse('n1:n2:login'))
    print(reverse('n1:logout'))
    return HttpResponse('...')	

 

posted @ 2017-07-05 18:21  细雨蓝枫  阅读(173)  评论(0编辑  收藏  举报