Django的URLconf

Django的URLconf

一. 为了将URL和视图关联起来,Django使用了’URLconfs’来配置,URLconf将URL模式映射到视图。


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

这里使用<int:year>,目的是从url里面获取到value值。

二. Path converters

  • str---------可以匹配任何非空的字符串
  • int---------匹配到非负整数(0以及正整数),返回int类型
  • slug-------匹配slug string(比如building-your-1st-django-site就是slug string,slug string是为了解决url上面不能出现空格,所以在每个单词中间用横杠-代替空格。)
  • uuid-------匹配正式的uuid. 为了防止访问多个url都跳转到同一个网页,所以使用到uuid,唯一性而且数量还很多。一个uuid必须有短横杠,而且英语字母必须是 小写的,比如075194d3-6885-417e-a8a8-6c931e272f00是uuid, 返回UUID实例。
  • path------匹配非空的字段,包括分隔线/。

三. 注册自定义的path converter(路径转化器)

对于很复杂的对应要求,可以自己定义自己的path converter.

(一)对于一个path converter, 它是一个类,包含以下的东西:

  • 一个正则属性,类型是字符串类型
  • 一个to_python(self, value)方法,这个方法目的转换类型,把匹配的字符串转换成你想要的类型,然后将转换后的这个值传递到视图中去。
  • 一个to_url(self, value)方法,它的作用是把一个Python类型转换成字符串类型应用到url中

如下所示:

class FourDigitYearConverter:
    regex = '[0-9]{4}'

    def to_python(self, value):
        return int(value)

    def to_url(self, value):
        return '%04d' % value

(二)在URLconf里面使用register_converter()进行注册自定义的converter类

from django.urls import path, register_converter

from . import converters, views

register_converter(converters.FourDigitYearConverter, 'yyyy')

urlpatterns = [
	path('articles/2003/', views.special_case_2003),
	path('article/<yyyy:year>', views.year_archive),
	...
]

四. 使用正则表达式

when the path and converters syntax isn’t sufficient for defining your URL patterns, you can also use regular expressions. to do so, use re_path() instead of path()

如果url使用正则匹配,那在URLconf里面就用re_path来代替path. please keep the following regualtions in mind.

  • the syntax for named regular expression groups is (?Ppattern), name是组名, and pattern is some pattern to match.
  • each captured argument is sent to the view as a string, regardless of what sort of match the regular expression makes(正则匹配到的字段不管是什么类型,传递给view视图去都是字符串类型)
  • 使用正则表达式的规则时候,pattern group也可以不命名:([0-9]{4}) ,但是这种shorter unnamed group的方式是不推荐的,因为会很容易引入错误,当named group和unmamed group同时存在的时候,unnamed group会被忽视从而不会被传入到视图中去。
  • 正则表达式支持nested arguments. nested arguments的意思就是说:在匹配URL的时候,正则规则需要使用到这个参数,但是在view里面并不需要这个参数,所以不把这个参数传递给view,可以使用?:来进行忽略。请看示例二;

(一)示例一:named group regular expression

from django.urls import path, re_path
from . import views

urlpattern = [
	path('articles/2003/', views.special_case_2003),
	re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
	re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$',views.month_archive),
	re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$', views.article_detail),

]

(二)示例二:nested argument

from django.urls import re_path

urlpatterns = [
    re_path(r'^blog/(page-(\d+)/)?$', blog_articles),  # bad
    re_path(r'^comments/(?:page-(?P<page_number>\d+)/)?$', comments),  # good
]

假如url使用blog/page-2, 匹配到blog_articles时,会传递两个参数到views视图,page-2/2

第二个匹配到comments时候,会传递一个参数给视图,2, 因为第一个位置参数使用了?:

五. 指定视图参数的默认值

# URLconf
from django.urls import path
from . import views

urlpatterns = [
	path('blog/', views.page),
	path('blog/page<int:num>/', views.page), #int是指明num的类型,num是指明参数名

]

# View
def page(request, num=1):
	......
	#当匹配到第一个url, 那就会使用默认的num=1.
    #当匹配到第二个url,就会使用传入的真实的num

六. extra options

urlpatterns列表里面的path()有四个参数:

  1. 路由
  2. 对应的view名字
  3. 可选的,定义一个字典将关键字参数传入
  4. name, 是一个全局的name,在templates里面用得最多

现在我们讨论的就是第三个参数(可选参数):{‘foo’: ‘bar’}

(一). passing extra options to view functions

from django.urls import path
from . import views

urlpatterns = [
    path('blog/<int:year>/', views.year_archive, {'foo': 'bar'}),
]

(二). passing extra options to include()

# main.py
from django.urls import include, path

urlpatterns = [
    path('blog/', include('inner'), {'blog_id': 3}),
]

# inner.py
from django.urls import path
from mysite import views

urlpatterns = [
    path('archive/', views.archive),
    path('about/', views.about),
]

上面{'blog_id':3}是extra options, 通过include(‘inner’)把这个{'blog_id':3}传递给下面的archive函数和about函数了。

七. 反向解析

反向解析的意思就是找到对应的url地址。

对于反向解析,为了满足不同的层面(layers), Django提供了三个tools.

  • 在templates里面可以使用 url 这个template tag
  • 在views.py里面可以使用reverse()函数
  • 可以使用get_absolute_url
from django.urls import path

from . import views

urlpatterns = [
    #...
    path('articles/<int:year>/', views.year_archive, name='news-year-archive'),
    #...
]

在上面的URLconf里面已经定义了path, 如果想要找到/articles//这个路由地址,在templates可以通过如下的{% url ‘news-year-archive’ yearvar %}找到。

<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>
{# Or with the year in a template context variable: #}
<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
{% endfor %}
</ul>

在python code里面可以通过如下 return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))

找到URLconf里面定义的路由。

from django.http import HttpResponseRedirect
from django.urls import reverse

def redirect_to_year(request):
    # ...
    year = 2006
    # ...
    return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))

八. URL namespace

  1. application namespace

每一个应用的实例会有一个同样的命名空间。也就是多个实例共享一个命名空间。

  1. instance namespace
    • 实例命名空间定义了一个特定的应用的实例,实例命名空间需要在你的整个项目中都是独一无二的
    • 实例命名空间可以和应用命名空间一致,这被用作一个应用实例的默认实例
    • namespaced URLs使用":"来进行分割,比如admin:index指的就是admin 应用里面的index 页面。admin是namespace, index是URLconf里面每个path里面定义的name
    • 命名空间也可以是嵌套的,比如sports:polls:index,
发布了9 篇原创文章 · 获赞 8 · 访问量 174

猜你喜欢

转载自blog.csdn.net/weixin_46129834/article/details/105616239
今日推荐