300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Django视图层:嵌套参数 URLconf在查找什么?指定视图参数的默认值 include()路由转

Django视图层:嵌套参数 URLconf在查找什么?指定视图参数的默认值 include()路由转

时间:2019-10-14 07:48:45

相关推荐

Django视图层:嵌套参数 URLconf在查找什么?指定视图参数的默认值 include()路由转

一、视图层The view layer

Django 具有 “视图” 的概念,负责处理用户的请求并返回响应。

二、嵌套参数Nested arguments

正则表达式允许嵌套参数,Django 会处理参数并将参数传递给视图。

1、在 Python 正则表达式中,命名的正则表达式组的语法是(?P<name>pattern),匹配pattern并捕获匹配结果,设置name为组名,其中 **name 是组名,pattern 是要匹配的模式**。

1、第一步要导入from django.urls importre_path

2、命名的正则表达式组的写法(?P<name>pattern),P要大写,否则报错

3、urls.py和views.py的参数name组名要保持一致,否则报错

参数嵌套之后,形成内部参数、外部参数之分'^comments/(?:page-(?P<page_number>\d+)/)?$',则外面的(?:page-内部参数/)为外部参数,里面的(?P<page_number>\d+)为内部参数参数,有捕获参数、非捕获参数之分(?:pattern)或(pattern),匹配pattern但不捕获匹配结果。(?P<name> pattern) ,匹配pattern并捕获匹配结果,设置name为组名

2、在 Python 正则表达式中,未命名的正则表达式组

例如(?P<year>[0-9]{4}),或使用更短的未命名组,例如([0-9]{4})

与命名的正则表达式组的区别是没有name。

当混杂命名正则和未命名正则两种样式时,任何未命名的组都会被忽略,而且只有命名的组才会传递给视图函数。

不是特别推荐未命名的正则,因为它会更容易在匹配的预期含义和视图参数之间引发错误。在任何情况下,推荐在给定的正则表达式里只使用一个样式。当混杂命名正则和未命名正则两种样式时,任何未命名的组都会被忽略,而且只有命名的组才会传递给视图函数。

from django.urls import path, re_pathfrom mysite import viewsurlpatterns = [re_path(r"^blog/(page-(\d+)/)?$", views.blog_articles),# 不推荐此法re_path(r"^comments/(?:page-(?P<page_number>\d+))?$", ments)]

from django.http import HttpResponsedef blog_articles(request, page, num): # 不推荐此法return HttpResponse("这是嵌套参数示例一(不推荐此种写法)")def comments(request, page_number):return HttpResponse("这是嵌套参数示例二" + ":第" + page_number + "页")

当转换时,Django 将试着填充给所有外部捕捉参数,忽略任何嵌套捕捉参数。考虑下面可选的带有页面参数的 URL 模式:

1、示例中的两个模式都使用嵌套参数,并处理:例如, 第一个模式blog/page-2/ 将匹配给 blog_articles 并带有2个位置参数:page-2/ 和 2 。第二个模式comments/page-2/ 将匹配给 comments 并带有关键字参数 page_number=2 ,这个案例里的外部参数是一个非捕捉参数 (?:…) 。

2、blog_articles 视图需要反转最外层捕捉的参数,参数page-2/ 或在这里不需要参数,而 comments 可以在没有参数或有参数page_number=值的情况下反转。

3、嵌套捕捉参数在视图参数和 URL之间创建一个强耦合,正如 blog_articles 所示:视图接收部分 URL (page-2/) 而不只是视图要的值。当反转时这种耦合更明显,因为反转视图我们需要传递一段 URL 而不是 page number。

4、根据经验,只有当正则表达式需要一个参数但视图忽略它时,才捕捉该视图需要的值并使用非捕捉参数

二、URLconf在查找什么?

请求的URL被看做是一个普通的Python 字符串, URLconf在其上查找并匹配。进行匹配时将不包括GET或POST请求方式的参数以及域名。

例如, /myapp/ 请求中,URLconf 将查找 myapp/

在 /myapp/?page=3 请求中,URLconf 仍将查找 myapp/ 。

**URLconf 不检查使用了哪种请求方法。**换句话讲,所有的请求方法 —— 即,对同一个URL的无论是 POST请求 、 GET请求 、或 HEAD 请求方法等等 ——都将路由到相同的函数

三、指定视图参数的默认值

# URLconffrom django.urls import pathfrom mysite import viewsurlpatterns = [path("blog/", views.page),path("blog/page<int:num>/", views.page)]

注:views里的参数必须与url里的参数相同,即num

from django.http import HttpResponsedef page(request, num = 1):return HttpResponse("年现在访问的是page{}".format(num))

在上面的例子中,两个URL模式都指向了相同的视图—— views.page 但是第一个样式不能在URL中捕获到任意东西。如果第一个URL模式去匹配URL,page() 函数会使用它默认参数 num=1。如果第二个URL模式去匹配URL,page() 函数会使用捕获到的任意num参数。

四、include其它的URLconfs,方式一

在一般情况下,url可能不只简简单单的几个,而是很多,此时如果将需要匹配的url全部放到urlpatterns里面,就会显得有些冗余。include函数就应运而生了。每当Django遇到时include(),它会去掉URL中已经匹配的部分,并将剩余的字符串发送到包含的URLconf以进行进一步处理,也就是转发到二级路由去。

在任何时候,你的 urlpatterns 都可以 “include” 其它URLconf 模块。这实际上将一部分URL 放置于其它URL 下面。

第一步from django.urls import include, path

每当 Django 遇到 include() ,它会将匹配到该点的URLconf的任何部分切掉,并将剩余的字符串发送到包含的URLconf进行进一步处理。

可通过使用 path() 实例的列表来包含其他 URL 模式。

优点:这种方法可以去除URLconf 中的冗余,其中某个模式前缀被重复使用

from django.urls import path, includefrom mysite.main import views as main_viewfrom mysite.credit import views as credit_viewextra_patterns = [path("reports/<int:id>/", credit_view.reportinfo),path("charge/", credit_view.chargeinfo)]urlpatterns = [path("", main_view.homepage),path("credit/", include(extra_patterns))]

from django.http import HttpResponsedef chargeinfo(request):return HttpResponse("这是mysite.credit.views.charge呀")def reportinfo(request, id):return HttpResponse("这是mysite.credit.views.report呀,id=" + str(id))

HttpResponse是一个字符串,所以这里的int id要转换一下

五、include其它的URLconfs,方式二

from django.urls import pathfrom mysite import viewsurlpatterns = [path("<page_slug>-<page_id>/history/", views.history),path("<page_slug>-<page_id>/edit/", views.edit),path("<page_slug>-<page_id>/discuss/", views.discuss),path("<page_slug>-<page_id>/permissions/", views.permissions)]

from django.http import HttpResponsedef history(request, page_slug, page_id):return HttpResponse("这是history,page_slug的值是{},page_id的值是{}".format(page_slug,page_id))

改进:我们可以改进它,通过只声明一次共同的路径前缀,并将后面的部分分组

from django.urls import path, includefrom mysite import views# urlpatterns = [#path("<page_slug>-<page_id>/history/", views.history),#path("<page_slug>-<page_id>/edit/", views.edit),#path("<page_slug>-<page_id>/discuss/", views.discuss),#path("<page_slug>-<page_id>/permissions/", views.permissions)# ]urlpatterns = [path("<page_slug>-<page_id>/", include([path("history/", views.history),path("edit/", views.edit),path("discuss/", views.discuss),path("permissions/", views.permissions)]))]

六、include其它的URLconfs,方式三

被包含的URLconf 会收到来自父URLconf 捕获的任何参数,捕获的变量将被传递给include()指向的URLconf

# myproject/urls.pyfrom django.urls import path, includeurlpatterns = [path("<username>/blog/", include("mysite.urls")) # 父URLconf转发到mysite.urls.py里的二级路由]

被包含的URLconf 会收到来自父URLconf 捕获的任何参数,捕获的 “username” 变量将被传递给include()指向的URLconf

# mysite/urls.pyfrom django.urls import pathfrom mysite import viewsurlpatterns = [ # 二级路由mysite/urls.py接收父路由path("", views.blog),]

# mysite/views.pyfrom django.http import HttpResponsedef blog(request, username):return HttpResponse("这是include示例,参数username={}".format(username))

七、传递额外选项给 include()

同样的,可以传递额外其他选项给 include() ,并且已包含的 URLconf 里的每一行将被传递额外选项。

例如,下面两个 URLconf 配置,把kwargs写在一级路由里或二级路由里,在功能上是相同的:

方式一:把kwargs写在一级路由里,这种情况下,kwargs会一直传递给所包含的 URLconf 的每一项,不管视图是否接受这些额外参数。因此,这个技巧仅在确定所包含的 URLconf 中的每一个视图接受你传递的额外参数时有用。

# myproject/urls.pyfrom django.urls import path, includeurlpatterns = [path("blog/", include("mysite.urls"), {"blog_id":3}),]

# mysite/urls.pyfrom django.urls import pathfrom mysite import viewsurlpatterns = [path("archive/", views.archive),path("about/", views.about),]

# mysite/view.pyfrom django.http import HttpResponsedef archive(request, blog_id=3):return HttpResponse("这是archive,参数blog_id={}".format(blog_id))def about(request, blog_id=3):return HttpResponse("这是about,参数blog_id={}".format(blog_id))

方式二:把kwargs写在二级路由里

# myproject/urls.pyfrom django.urls import path, includeurlpatterns = [path("blog/", include("mysite.urls")),]

# mysite/urls.pyfrom django.urls import pathfrom mysite import viewsurlpatterns = [path("archive/", views.archive, {"blog_id":3}),path("about/", views.about, {"blog_id":3}),]

# mysite/view.py 保持不变

八、传递kwargs给视图

path(route, view, kwargs=None, name=None, Pattern=None)kwargs为字典,作为关键字参数传给视图URLconfs 有钩子来允许你把其他参数作为 Python 字典来传递给视图函数。path() 函数可带有可选的第三参数(必须是字典),传递到视图函数里。

from django.urls import path, includefrom mysite import viewsurlpatterns = [path("<username>/blog/", views.blog, {"foo":"bar"})]

from django.http import HttpResponsedef blog(request, username, foo="bar"):return HttpResponse("这是include示例,参数username={},参数foo={}".format(username,foo))

source,Django

Django视图层:嵌套参数 URLconf在查找什么?指定视图参数的默认值 include()路由转发三种方式 传递额外选项给 include() 传递额外选项给视图

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。