首页 > 技术文章 > 2.URl配置

journeyer-xsh 2020-08-17 08:13 原文

一、URl配置

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

1、无名分组

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

以下是django 2.0 以上的写法:

from django.urls import 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),
]

参数说明:

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

加位置参数:

加$是原因是url函数只要配到到就执行相应的视图函数,不在向后匹配了。

url(r'books/(\d){4}/$', views.year_books),
    url(r'books/(\d){4}/(\d){1,2}/', views.year_month_books),

对应的视图函数:

def year_books(request, year):
    print(year)
    return HttpResponse(year)

def year_month_books(request, year, month):		# 位置参数,第一个参数接受的就是无名分组中第一个匹配到的分组的数据,第二个参数就是接受第二个分组匹配到的数据
    print(year, month)
    return HttpResponse(year, month)

2、有名分组:

有名分组采用分组命名匹配的方法,

urls:

url(r'^books/(?P<year>\d{4})/(?P<month>\d{1,2})/', views.year_month_books),

视图函数:

# 有名分组,只要形参名和urls中的分组名一样,参数位置无所谓
def year_month_books(request, month, year):
    print(month, year)
    return HttpResponse(month, year)

在setting中setting.py中手动加上APPEND_SLASH = False可以设置浏览器中输入的url不加最后一个/也可以访问,对应的urls.py中的url的最后一个/也不用写,如果APPEND_SLASH=True(默认)则会自动加上/。

3、URLconf匹配的位置

URLconf不检查请求方法,同一个的URL的POST、GET、HEAD等等,这些路由到同一个函数。

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

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

url(r'^books/(?P<year>{4})/$', views.books)

4、视图函数指定默认值

# 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="123"):
    pass

5、url路由分发之include

增加app

  • 在创建django项目的时候创建
  • 在项目的根目录下打开cmd输入python manage.py startapp app02即可创建一个名为app02,这在pycharm的终端中输入也可以
  • 在setting.py中添加app02

在项目中的urls.py可以写,这样在访问时需要在端口后面写app01或者app02,否则报错。

# 这HelloDjango中的urls.py不是app01中的urls.py
urlpatterns = [
    # http://127.0.0.0.1:9000/app01/asd
    url('app01/', include('app01.urls')),
    # http://127.0.0.0.1:9000/app02/erdf
    url('app02/', include('app02.urls')),
    # 首页
    url(r'$', views.base),
    
]

在应用时:

# 在html文件中
<a href='{% url 'app01:home' %}'>返回首页</a>
    
# 在后端文件中
return redirect('app01:book1')

二、url正则表达式详解

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^articles/2020/$', views.special_case_2020), #如果用户想看2019、2020、2021等,你要写一堆的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别名和反向解析

1、设置url别名

再home1的后面设置他的别名是home,其他文件中需要引用这个url就可以直接使用别名。即使home1改成别的名字,其他文件中引用这个url的也不需要改名,直接使用home即可。

# urls.py
url(r'home1', views.home, name='home')

2、反向解析

from django.urls import reverse
from django.shortcuts import redirect
reverse('别名')
# 重定向时使用reverse解析
return redirect(reverse('home'))
# 或者不使用,django也会自动解析
return redirect('home')

再html文件中引用

<a href='{% url 'home' %}'>主页面</a>

带参数的反向解析

reverse('index', args=(10, 12))   # /index/10/

{% url '别名' 参数1 参数2 %} 
例如:{% url 'index' 10 %} -- /index2/10/  <a href='/index2/10/'>hhh</a>

推荐阅读