路由分发
研究django admin源码时:
namespace是什么?
-
无namespace
from django.urls import reverse url = reverse("v2") print(url)
-
有namespace
from django.urls import reverse url = reverse("namespace名称:v2") print(url) url = reverse("namespace名称:namespace名称:v2") print(url)
问题:什么叫反向
生成?
path('login/login/login/login/', views.login, name='login'),
路由本质
关于导入和反射
- 反射,以字符串的形式去操作对象中的成员。
- 导入模块
include源码
urlpatterns = [
path('login/', views.login),
path('api/', include("apps.base.urls")),
path('api/', (
import_module("apps.base.urls"), # 模块对象 from app.base import urls
None,
None)
)
]
urlpatterns = [
path('login/', views.login),
path('api/', include("apps.base.urls")),
path('api/', (
import_module("apps.base.urls"), # 模块对象 from app.base import urls
None,
None)
),
path('web/', (
[
path('v1/', www_views.login, name='v1'),
path('v2/', www_views.login, name='v2'),
],
None,
None)
),
]
在path执行时,传入的参数种类:
-
网址 + 函数
-
网址 + (模块对象,None,None)
urlpatterns = [ ... ]
-
网址 + (列表,None,None)
path源码
-
网址 + 函数
path('login/', views.login), URLPattern( RoutePattern("login/", name=None, is_endpoint=True), views.login, None, None )
-
网址 + (模块对象,None,None)
path('api/', include("apps.base.urls")), path('api/', ( import_module("apps.base.urls"), # 模块对象 from app.base import urls None, None) ), URLResolver( RoutePattern('api/',name=None,is_endpoint=False), import_module("apps.base.urls"), # 模块对象 from app.base import urls None, app_name=None, namespace=None )
-
网址 + (列表,None,None)
path('web/', ( [ path('v1/', www_views.login, name='v1'), path('v2/', www_views.login, name='v2'), ], None, None) ) URLResolver( RoutePattern('api/',name=None,is_endpoint=False), [ path('v1/', www_views.login, name='v1'), path('v2/', www_views.login, name='v2'), ], None, app_name=None, namespace=None )
所有URL用类和对象嵌套的形式实现:
from django.urls import path, re_path, include
from apps.www import views
from django.urls import URLPattern, ResolverMatch
from django.urls.resolvers import RoutePattern
from importlib import import_module
from apps.www import views as www_views
from django.urls.resolvers import URLResolver
urlpatterns = [
URLPattern(
RoutePattern("login/", name=None, is_endpoint=True),
views.login,
None,
None
),
URLResolver(
RoutePattern('api/', name=None, is_endpoint=False),
import_module("apps.base.urls"), # 模块对象 from app.base import urls
None,
app_name=None,
namespace=None
),
URLResolver(
RoutePattern('web/', name=None, is_endpoint=False),
[
path('v1/', www_views.login, name='v1'),
path('v2/', www_views.login, name='v2'),
],
None,
app_name=None,
namespace=None
)
]
路由匹配源码
1.请求来了
2.路由匹配
3.匹配过程
答疑:多个app的时候,路由分发到不同的app里,如果1个app,有100个路由,能不能按大类功能进行分组。
path('api/user/login/', views.login, name='login'),
path('api/user/logout/', views.login, name='login'),
path('api/user/order/', views.login, name='login'),
path('api/user/info/', views.login, name='login'),
path('api/user/ad/', views.login, name='login'),
关于网址之后的 /
-
APPEND_SLASH = True
path('login/', views.login, name='login') http://127.0.0.1:8000/login/ 成功 http://127.0.0.1:8000/login 重定向,GET http://127.0.0.1:8000/login/
当我们直接访问网址或GET请求访问网址,都会成功,如果是POST请求有问题。
-
APPEND_SLASH = False
path('login/', views.login, name='login') http://127.0.0.1:8000/login/ 成功 http://127.0.0.1:8000/login 失败 path('login', views.login, name='login') http://127.0.0.1:8000/login/ 失败 http://127.0.0.1:8000/login 成功
严格模式,自己定义是什么就以什么方式访问。