Django路由系统

序章

Django如何处理一个请求:
  1. 项目启动后根据settings 文件中 ROOT_URL_CONF 决定根URLconf
  2. 它是django.conf.urls.url()  实例的一个python列表
  3. Django 依次匹配每个URL模式,在与请求的URL匹配到第一个模式停下来。
  4. 一旦其中的一个正则表达式匹配上了,Django将导入并调用给出的视图,它是一个简单的python函数(或者一个基于类的视图)。视图将获得如下参数:
    • 一个HttpRequest 实例
    • 如果匹配的正则表达式返回了没有命名的组,那么正则表达式匹配的内容将作为位置参数提供给视图。
    • 关键字参数由正则表达式匹配给的命名组成,但是可以被django.conf.urls.url()的可选参数kwargs覆盖。
  5. 如果没有匹配到正则表达式,或者过程中抛出异常,将调用一个适当的错误函数处理视图。 

 

  Django的URL和Views的配置哲学:松耦合,简单的说就是URL指定视图函数和视图函数的具体实现是在两个不同的地方,实现开发者修改一个配置而不影响另外一个配置。

路由系统的使用

  路由系统的核心规则:匹配方式为自上而下,匹配到第一条就会忽略后面所有规则!所以路由的顺序很重要!

# urls
from django.conf.urls import url, include
from django.contrib import admin
from myapp import views  # 导入myapp项目中的view文件
from anotherapp import urls as otherurls
urlpatterns = [
    # admin管理页面
    url(r'^admin/',  admin.site.urls),
    # 默认页面,http://127.0.0.1                     
    url(r'^$',  views.index),
    # 登录页面, http://127.0.0.1/login/                                     
    url(r'^login/$',  views.login, name='login'), 
    # 动态路由(传递一个参数),常用用于urls过多,通过正则来完成,比如分页系统 ,小括号表示分组     
    url(r'^book1/(\d+)/$',  views.book),
    # 动态路由(传递多个参数),传递两个数字给book1函数 ,url传递几个参数,后端函数就要接收几个参数,按序(位置)传参     
    url(r'^book2/(\d+)/(\d+)/$',  views.book1),
    # 动态路由(key:value关键字形式),k1,k2即为关键字, k1是一个字符串,k2则是零个或一个数字
    url(r'^book3/(?P<k1>[\w|-]+)/(?P<k2>\d*)/$',  views.book2), 
    # 二级路由,包含其他的urls路由, http://127.0.0.1/blog/下面所有的路径
    url(r'blog/',  include('blog.urls')), 
    url(r'other/', include(otherurls)),
]
# views
from django.shortcuts import render,HttpResponse 
def book1(request):
    return HttpResponse('book1')

def book2(request,num):
     print(num)
     return HttpResponse('book2')

def books3(request,k1,k2):
   print(k1,k2)     
     return HttpResponse('book3')

 

# include
相当于二级路由策略,它接收到的url地址去除了它前面的正则表达式,将剩下的字符串传递给下一级路由进行判断。
建议:除了admin路由外,每个app都应该设计自己独立的二级路由

# url 
     url()函数可以传递4个参数,其中2个是必须的:regex 和 view, 以及2个可选参数:kwargs和name。
regex:
     regex是正则表达式的通用缩写, 它是一种匹配字符串或url地址的语法。django通过用户请求地址,在urls.py文件中对urlpatterns列表中的 
name:
     可以用于templates,models,views,通过name获取对应的url网址,相当于给网址起一个别名,注意name不要重复。
    # URL name 在template中的用法
    <a href="{% url 'key_list' %}">主机管理</a>              # 普通的url name示例
    <a href="{% url 'group_list' args %}">分组管理</a>  # url 需要传递参数的name示例
    <a href="{% url 'app01:group' pk=11 pp=99 %}">分组查询</a>
    # 在代码层使用
     v = reverse('app01:group', kwargs={'pk':11})
    # 上面是html 文件的节选,在a标签中网址,使用的模板语言,模板中用的就是url name,这样用的好处就是即使网页地址变更,只要url             name 不变就可以继续访问页面。

 

路由规则中的正则表达式:

.(dot)       任意单一字符
\d           任意一位数字
[A-Z]        A 到 Z 中任意一个字符(大写)
[a-z]        a 到 z 中任意一个字符(小写)
[A-Za-z]     a 到 z 中任意一个字符(不区分大小写)
+            匹配一个或更多(eg: \d+ 匹配一个或多个数字字符)
[^/]+        一个或多个不为'/'的字符
?            零个或一个之前的表达式(eg:\d? 匹配零个或一个数字)
*            匹配0个或更多(eg: \d* 匹配0个或更多数字字符)
{1,3}        介于一个和三个(包含三个)之前的表达式(eg: \d{1,3}匹配一个或两个或三个数字)

 

反向解析URL:

  • 在模板语言中:使用url 模板标签
  • 在Python代码中,使用 reverse() 函数
  • 在更高层的,处理Django模型实例相关代码中:使用 get_absolute_url() 方法
# 遇见的两种导解析方式
(1)第一种方式,绝对路径解析:
from django.http import HttpResponseRedirect
def f1(request):
    pass
    return HttpResponseRedirect('/classroom/notamember/%s/' % classname)

(2)第二种方式,reverse
from django.core.urlresolvers import reverse
from django.urls import reverse

def f2(request):
    pass
    url = reverse('notamember', kwargs={'classname': classname})
    return HttpResponseRedirect(url)

 

 

 

posted @ 2016-09-10 10:26  Auvღ  阅读(138)  评论(0)    收藏  举报