一、django如何处理请求
1.在settings.py目录下配置好ROOT_URLCONF = '根目录名.urls'
2.通过根目录下from django.conf.urls import url
,创建urlpatterns
列表
3.通过用户输入的url和urlpatterns
中的url进行匹配
4.匹配成功后,导入并调用给定的视图python函数
5.如果匹配失败返回报错信息
二、匹配/分组算法
- 以位置参数传递所有的非命名参数。
- 有命名参数,则使用这些命名参数,忽略非命名参数。
三、获取一组url
1.所有url都是str类型,例如/test/1,中的1也是str类型
2.获取一组url,获取/test/2017、/test/2018这种变化的url
-
注:
- 如果要从URL 中捕获一个值,只需要用
()
包裹住 - 不需要在每个url前加反斜杠,因为每个url都有
- 每个正则表达式前面的'r' 是可选的但是建议加上。 它告诉Python 这个字符串是“原始的” —— 字符串中任何字符都不应该转义。
-
一 一对应例:
urlpatterns = [
url(r'^test/([0-9]{4})/$',views.index),
url(r'^test/([0-9]{4})/([0-9]{2})/$',views.index1),
url(r'^test/([0-9]{4})/([0-9]{2})/([0-9]+)/$',views.index2),
]
对应的函数接收的参数是依次对应关系
def index(request,yid)
def index1(request,yid,mid)
def index2(request,yid,mid,did)
-
命名组通过属性名对应
格式(?P<属性名>)
urlpatterns = [
url(r'^test/(?P[0-9]{4})/$',views.index),
url(r'^test/(?P[0-9]{4})/(?P[0-9]{2})/$',views.index1),
url(r'^test/(?P[0-9]{4})/(?P[0-9]{2})/(?P[0-9]+)/$',views.index2),
]
对应函数为属性名依次对应,函数中的属性名位置可以不用顺序排列
def index(request,year):
def index1(request,month,year):
def index2(request,year,month,day):
-
通过get获取一组url
1.请求的URL被看做是一个普通的Python 字符串, URLconf在其上查找并匹配。 进行匹配时将不包括GET或POST请求方式的参数以及域名
2.但我们可通过传统的?来拼接url,通过methon.GET.get()
来获取
三、正向解析小技巧
-
两个url指向同一函数通过设置默认值跳转
我们可以通过设置默认值做到,让连接做到选着跳转,先写;两个前缀一致的url,通过函数设置默认值,网页默认跳转第一页
urlpatterns = [
url(r'^test/page/$',views.index),
url(r'^test/page(?P(\d+))/$',views.index),
]
对应的函数写法:
def index(request,page=1):
return HttpResponse(page)
-
include 包括
1.将连接引导到app模块的urls.py上
from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
#将url引导到别的app urls文件下
url(r'^polls/',include('polls.urls'))
]
2.将统一前缀的分组分发
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^(?P[\w-]+)-(?P\w+)/history/$', views.history),
url(r'^(?P[\w-]+)-(?P\w+)/edit/$', views.edit),
url(r'^(?P[\w-]+)-(?P\w+)/discuss/$', views.discuss),
url(r'^(?P[\w-]+)-(?P\w+)/permissions/$', views.permissions),
]
我们可以改进它,通过只声明共同的路径前缀一次并将后面的部分分组:
from django.conf.urls import include, url
from . import views
urlpatterns = [
url(r'^(?P[\w-]+)-(?P\w+)/', include([
url(r'^history/$', views.history),
url(r'^edit/$', views.edit),
url(r'^discuss/$', views.discuss),
url(r'^permissions/$', views.permissions),
])),
]
3.根目录url也可以传递值给子url
根目录url,子url对应的函数也会接受到参数
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^polls/(\d+)/',include('polls.urls'))
]
4.非捕获组方式更有效
from django.conf.urls import url
urlpatterns = [
url(r'blog/(page-(\d+)/)?$', blog_articles), # bad
url(r'comments/(?:page-(?P\d+)/)?$', comments), # good
]
5.通过字典传递固定值
注:
URL 模式捕获的命名关键字参数和在字典中传递的额外参数有可能具有相同的名称。 当这种情况发生时,将使用字典中的参数而不是URL 中捕获的参数。
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^blog/(?P[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]
在这个例子中,对于/blog/2005/请求,Django 将调用views.year_archive(request, year='2005', foo='bar')
四、反向解析小技巧
考虑下面的URLconf:
from django.conf.urls import url
from . import views
urlpatterns = [
#...
url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'),
#...
]
根据这里的设计,某一年nnnn对应的归档的URL是/articles/nnnn/。
你可以在模板的代码中使用下面的方法获得它们:
2012
{%for i in year_list%}
{{i}}
{%endfor%}
在Python 代码中,这样使用:
from django.urls import reverse
from django.http import HttpResponseRedirect
def redirect_to_year(request):
# ...
year = 2006
# ...
return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))