Django框架全面讲解 -- Django 路由系统

Django框架全面讲解 -- Django 路由系统

URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。URL的加载是从配置文件中开始。 

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

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),
]
  •  

说明: 
要捕获从URL中的值,用括号括起来,会当参数传入 views 视图。 
没有必要添加一个斜线,因为每个URL都有。例如,它^articles不是^/articles。 
在’r’前面的每个正则表达式字符串中是可选的,但建议。它告诉Python字符串是“原始” -没有什么字符串中应该进行转义。 
请求示例: 
一个请求 /articles/2005/03/ 会匹配上面列表中的第三条. Django 会调用函数 views.month_archive(request, ‘2005’, ‘03’). 
/articles/2005/3/ 不会匹配上面列表中的任何条目, 因为第三条的月份需要二位数字. 
/articles/2003/ 会匹配上第一条而不是第二条,因为匹配是按照从上到下顺序而进行的, Django 会调用函数 views.special_case_2003(request) 
/articles/2003 不会匹配上面列表中的任何条目, 因为每个URL应该以 / 结尾. 
/articles/2003/03/03/ 会匹配上最后一条. Django 会调用函数 views.article_detail(request, ‘2003’, ‘03’, ‘03’). 
2. 命名组(Named groups) 
在上面的简单例子中,并没有使用正则表达式分组,在更高级的用法中,很有可能使用正则分组来匹配URL并且将分组值通过参数传递给view函数。 
在Python的正则表达式中,分组的语法是 (?Ppattern), name表示分组名,pattern表示一些匹配正则. 
这里是一个简单的小例子:

# 正则知识
import re

ret=re.search('(?P<id>\d{3})/(?P<name>\w{3})','weeew34ttt123/ooo')

print(ret.group())
print(ret.group('id'))
print(ret.group('name'))
-------------------------------------
123/ooo
123
ooo
  •  
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),
]
  •  

For example:

A request to /articles/2005/03/ 会调用函数 views.month_archive(request, year='2005',month='03'), 而不是 views.month_archive(request, '2005', '03').
A request to /articles/2003/03/03/ 会调用函数 views.article_detail(request, year='2003',month='03', day='03').
  •  

常见写法实例: 

3. 二级路由(Including) 
那如果映射 url 太多怎么办,全写一个在 urlpatterns 显得繁琐,so 二级路由应用而生

from django.conf.urls import include, url

from apps.main import views as main_views
from credit import views as credit_views

extra_patterns = [
    url(r'^reports/$', credit_views.report),
    url(r'^reports/(?P<id>[0-9]+)/$', credit_views.report),
    url(r'^charge/$', credit_views.charge),
]

urlpatterns = [
    url(r'^$', main_views.homepage),
    url(r'^help/', include('apps.help.urls')),
    url(r'^credit/', include(extra_patterns)),
]
  •  

在上面这个例子中,如果请求url为 /credit/reports/ 则会调用函数 credit_views.report(). 
使用二级路由也可以减少代码冗余,使代码更加简洁易懂。

# 原始版本
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/history/$', views.history),
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/edit/$', views.edit),
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/discuss/$', views.discuss),
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/permissions/$', views.permissions),
]


# 改进版本
from django.conf.urls import include, url
from . import views

urlpatterns = [
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/', include([
        url(r'^history/$', views.history),
        url(r'^edit/$', views.edit),
        url(r'^discuss/$', views.discuss),
        url(r'^permissions/$', views.permissions),
    ])),
]
  •  

4.添加额外的参数 
URLconfs 有一个钩子可以让你加入一些额外的参数到view函数中.

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 将会调用函数l views.year_archive(request, year=’2017’,foo=’bar’). 
需要注意的是,当你加上参数时,对应函数views.year_archive必须加上一个参数,参数名也必须命名为 foo,如下:

def year_archive(request, foo):
    print(foo)
    return render(request, 'index.html')
  •  

5.别名的使用

url(r'^index',views.index,name='bieming')
  •  

url中还支持name参数的配置,如果配置了name属性,在模板的文件中就可以使用name值来代替相应的url值.我们来看一个例子:

urlpatterns = [
    url(r'^index',views.index,name='bieming'),
    url(r'^admin/', admin.site.urls),
    # 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),

]
###################
def index(req):
    if req.method=='POST':
        username=req.POST.get('username')
        password=req.POST.get('password')
        if username=='alex' and password=='123':
            return HttpResponse("登陆成功")
    return render(req,'index.html')
#####################
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{#     <form action="/index/" method="post">#}
{#     这里只要使用bieming即可代替/index #}
     <form action="{% url 'bieming' %}" method="post">
         用户名:<input type="text" name="username">
         密码:<input type="password" name="password">
         <input type="submit" value="submit">
     </form>
</body>
</html>
#######################
  •  

6.指定view的默认配置

# URLconf
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),
]

# View (in blog/views.py)
def page(request, num="1"):
    # Output the appropriate page of blog entries, according to num.
    ...
  •  

在上述的例子中,两个 URL 模式指向同一个视图 views.page 但第一图案不捕获从 URL 任何东西。如果第一个模式匹配,该 page() 函数将使用它的默认参数 num,”1”。如果第二图案相匹配时, page()将使用任何 num 值由正则表达式捕获。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shentong1/article/details/78813557

猜你喜欢

转载自blog.csdn.net/qq_34802511/article/details/81407933
今日推荐