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