路由系统
1 常见操作
通俗的语言来表示:URL -> 函数对应关系
2 路由源码分析
2.1 路由定义的本质
from django.urls import path, re_path
from apps.www import viewsfrom django.urls import URLPattern
from django.urls.resolvers import RoutePatternurlpatterns = [URLPattern(RoutePattern("login/", name=None, is_endpoint=True), views.login, None, None),path('login/', views.login, name='n1'),# http://127.0.0.1:8000/info/2222/# http://127.0.0.1:8000/info/2222/?a1=1&b1=2# path('info/<int:v1>/', views.info),# http://127.0.0.1:8000/other/11/wupeiqi/# http://127.0.0.1:8000/other/222/alex/# path('other/<int:v1>/<str:v2>/', views.other),# path('xx/<path:v2>/', views.xx),# path('xx/<uuid:v2>/', views.xx),# http://127.0.0.1:8000/yy/2014-11-11# re_path(r'yy/(\d{4})-(\d{2})-(\d{2})/', views.yy),
]
-
编写路由
-
启动项目时
urlpatterns = [对象(URL地址、函数),对象(URL地址、函数),对象,对象,对象,URLPattern(RoutePattern("login/", name=None, is_endpoint=True), views.login, None, None), ]# 内部路由匹配的时,默认执行: URLPattern.resolveself.pattern.match()return ResolverMatch(...)# 进阶操作 # 路由系统中的扩展点:URLPattern.resolveRoutePattern.match自定义ResolverMatch类
-
用户浏览器访问
http://127.0.0.1:8000/login/
-
django的源码内部,一定会匹配,获得相应的视图函数
http://127.0.0.1:8000 /login/urlpatterns = [对象(URL地址、函数),对象(URL地址、函数),对象,对象,对象 ]
urlconf = 'day006.urls' resolver = URLResolver(RegexPattern(r"^/"), urlconf)resolver_match = resolver.resolve(request.path_info)callback, callback_args, callback_kwargs = resolver_match
-
执行视图函数
urlpatterns = [path('login/', views.login),path('info/<int:v1>/', views.info), ]
urlpatterns = [URLPattern(RoutePattern("login/", name=None, is_endpoint=True), views.login, None, None),URLPattern(RoutePattern("login/", name=None, is_endpoint=True), views.login, None, None),URLPattern(RoutePattern("login/", name=None, is_endpoint=True), views.login, None, None),URLPattern(RoutePattern("login/", name=None, is_endpoint=True), views.login, None, None), ]
-
源码内部路由匹配的时,是怎么做的?
URLPattern.resolveRoutePattern.match
def resolve(self, path):match = self.pattern.match(path)if match:new_path, args, captured_kwargs = match# Pass any default args as **kwargs.kwargs = {**captured_kwargs, **self.default_args}return ResolverMatch(self.callback,args,kwargs,self.pattern.name,route=str(self.pattern),captured_kwargs=captured_kwargs,extra_kwargs=self.default_args,)
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 Nonereturn path[match.end() :], (), kwargsreturn None
2.3 name别名
path('login/', views.login, name='n1'),
URLPattern(RoutePattern("login/", name="n1", is_endpoint=True), views.login, None, "n1"),
def login(request):return HttpResponse("欢迎登陆")
from django.urls import reverseresult = reverse("n1")
print(result) # "login/"
path('api/auth/login/<int:v1>/', views.login, name='n1'),
def login(request,v1):return HttpResponse("欢迎登陆")
from django.urls import reverseresult = reverse("n1",kwargs={"v1":123})
print(result) # "/api/auth/login/123/"result = reverse("n1",kwargs={"v1":999})
print(result) # "/api/auth/login/999/"
name存在的意义?例如:用户登录登录程序
/api/auth/login/ -> 函数登录
/api/user/account/ -> 函数账单
path('api/auth/login/', views.login, name='n1'),
path('api/user/account/', views.account, name='n2'),
def login(request):# 当用户登录成功之后,需要让用户跳转到 /api/user/account/ 页面# return redirect("/api/user/account/")# url = reverse("n2") # "/api/user/account/"# return redirect(url)return redirect("n2")def account(request):return HttpResponse("用户信息")
name存在的意义?例如:权限管理
A用户有权访问的网址:/api/auth/login/ /api/user/account//api/user/order//api/user/order/<int:v1>/B用户有权访问的网址:/api/user/account//api/user/order//api/user/order/<int:v1>/
A用户有权访问的网址:n1n2n3B用户有权访问的网址:n2n3