关于Django的url和path

我是一个Django的新手。

当我写Django2版本时,在urls.py中出现

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""

因为引起了我的兴趣,所以我稍微进行了一些调查。

在Django 1.x版本中,应该如何书写?

当你学习Django的教程时,会涉及到urls.py。

from django.contrib import admin
from django.conf.urls import url, include

urlpatterns = [
   url('', include('myapp.urls'))
   url(r'^admin/', admin.site.urls),
]

我认为可能会有些人会像这样写的。
这是根据urlpattern将admin或myapp.urls中指定的模板进行展开的过程。

在Django2版本中

from django.contrib import admin
from django.urls import path, include, re_path

urlpatterns = [
   path('', include('myapp.urls'))
   re_path(r'admin/', admin.site.urls),
]

有一种类似的感觉。

根据Django 2.0版本发布说明所示

简化的URL路由语法¶
新的django.urls.path()函数允许更简单、更易读的URL路由语法。例如,之前Django版本的如下语句:

url(r’^articles/(?P[0-9]{4})/$’, views.year_archive),
可以被写成:

path(‘articles/int:year/’, views.year_archive)
新的语法支持URL参数的类型强制转换。在上面的例子中,视图将以整数形式接收year关键字参数,而不是字符串形式。此外,在重写的例子中,匹配的URL稍微不受限制。举个例子,年份为10000的URL现在也会匹配成功,因为年份的整数位数没有像正则表达式中限制的那样必须是四位。

之前版本的django.conf.urls.url()函数现在可以通过django.urls.re_path()来使用。旧的函数位置还是保留下来以确保向后兼容,没有即将废弃的迹象。旧的django.conf.urls.include()函数现在可以在django.urls中导入,因此在URLconfs中可以使用from django.urls import include、path、re_path。

重写的URL调度器文档展示了新的语法,并提供了更多细节。

据说是这样。简单的中文翻译是

    • もっとシンプルで、読みやすいurlルーティングを作った。

 

    • pathは型強制(Type Hintsみたいなものかな)をサポートしている

 

    • 昔のやつは後方互換性のために残していて、すぐに消したりはしない

 

    • django.conf.urls.url() == django.urls.re_path()

 

    includeもdjango.urlsに入っている

好像是这种感觉。

你是谁?

当我查看GitHub上的Django时,我发现django.conf.urls的url已经被替换为re_path了。

那么,path和re_path有什么不同呢?
我来查看一下Django的conf.py和resolver.py。

path = partial(_path, Pattern=RoutePattern) 
re_path = partial(_path, Pattern=RegexPattern) 

这个好像是Pattern的不同之处。最终,_path返回一个URLResolver,所以看一下那一块,开头使用了match方法。简单来说,通过比较match方法。

    def __init__(self, route, ...):
        ...
        self.converters = _route_to_regex(str(route), is_endpoint)[1]

    def match(self, path):
        match = self.regex.search(path)
        if match:
            # RoutePattern doesn't allow non-named groups so args are ignored.
            kwargs = match.groupdict()
            for key, value in kwargs.items():
                converter = self.converters[key]
                try:
                    kwargs[key] = converter.to_python(value)
                except ValueError:
                    return None
            return path[match.end():], (), kwargs
        return None

RoutePattern接受urlpattern作为参数,将其转换为正则表达式,然后再转换回UUID并返回。

    def match(self, path):
        match = self.regex.search(path)
        if match:
            # RoutePattern doesn't allow non-named groups so args are ignored.
            kwargs = match.groupdict()
            for key, value in kwargs.items():
                converter = self.converters[key]
                try:
                    kwargs[key] = converter.to_python(value)
                except ValueError:
                    return None
            return path[match.end():], (), kwargs
        return None

正则表达式模式是根据提供的正则表达式进行匹配并返回的实现,是这样理解吗?
* 我有点困惑了。

总结

因为我对这方面不是很了解,所以不能给出很具体的建议,但是无论是使用path还是re_path,最终都会使用正则表达式进行匹配。
所以,我觉得使用path会更简单一些,我可能会选择使用它。
请教更懂的人给我更详细的建议。

广告
将在 10 秒后关闭
bannerAds