本质上:URL和函数的对应关系。
示例:包含一个apps,内含两个app device和asserts
路由分发方式为通过主路由找分app的路由,在app的路由内找本app的views
主路由urls
from django.urls import path,include
urlpatterns = [
path('device/',include("apps.device.urls")),
path('asserts/',include("apps.asserts.urls")),
# 注意不要在device前加/,那样就出问题了
]
device 的urls
需要在文件内定义app_name
from django.urls import path,re_path
from apps.device import views
urlpatterns = [
path('home/',views.home),
path('web/',views.web),
]
app_name="device"
device内的views
from django.shortcuts import render,HttpResponse
def home(request):
return HttpResponse("home page")
def web(request):
return HttpResponse("web page")
这里不用定义app_name
假如:200个功能。
inlucde + app(一般),将功能拆分不到不同的app中。 但是要定义每一个app的app_name到urls内
手动路由分发,可以与app无关。 可以不定义app_name
path('user/add/', views.login),
path('user/delete/', views.login),
path('user/edit/', views.login),
path('user/list/', views.login),
path('user/', ([
path('add/', views.login),
path('delete/', views.login), # /user/delete/
path('edit/', views.login),
path('list/', views.login),
], None, None)),
纯粹帮助提取功能的URL,防止重复编写。
路由分发的本质:
URL对应函数
path('user/add/', views.login),
URL对应元组
path('user/add/', (元素,appname元素,namespance元素) ),
path('user/add/', include("apps.api.urls") ), # 查看include 也是元组
path('user/add/', ([],None,None) ),
include或手动元组列表,本质相同。
应用场景和意义,想要把一些URL前缀提取出来。
path('user/add/', views.login),
path('user/delete/', views.login),
path('user/edit/', views.login),
path('user/list/', views.login),
path('user/', ([
path('add/', views.login),
path('delete/', views.login), # /user/delete/
path('edit/', views.login),
path('list/', views.login),
], None, None)),
path('users', include(([
path('add/', views.login),
path('delete/', views.login), # /user/delete/
path('edit/', views.login),
path('list/', views.login),
], None))),
include("apps.api.urls") # 一般是每个app中urls
urlpatterns = [
]
name是可以用于单APP的情况,如果是多APP的话,需要为每个app添加单独的namespace
给一个路由起个名字 + 根据名字反向生成URL。
urlpatterns = [
path('login/', views.login),
]
# 很多功能,很多URL
urlpatterns = [
path('login/', views.login, name="v1"),
path('auth/', views.auth, name="v2"),
]
有了名字后,以后一般有两处会用到:
在视图函数中生成URL
from django.urls import reverse
url = reverse("v2") # /auth/
url = reverse("v1") # /login/
HTML模板,页面上有一个a标签,添加xx。
<a href="/xxx/xxx/xx/">添加a>
<a href="{% url 'v1' %}">添加a>
<a href="{% url 'v2' %}">添加a>
扩展
以后做权限管理,让name属性配合。
辅助name。
主路由 主路由是namespace
from django.urls import path, re_path, include
# 很多功能,很多URL
urlpatterns = [
path('api/', include("apps.api.urls",namespace='x1')),
path('web/', include("apps.web.urls",namespace='x2')),
]
api/urls.py
from django.urls import path, re_path
from . import views
# 很多功能,很多URL
urlpatterns = [
path('login/', views.login,name="login"),
path('auth/', views.auth, name='auth'),
]
web/urls.py
from django.urls import path, re_path
from . import views
# 很多功能,很多URL
urlpatterns = [
path('home/', views.home,name='home'),
path('order/', views.order,name='order'),
path('auth/', views.order, name='auth'),
]
以后再某个URL或者视图中反向生成:
from django.urls import reverse
url = reverse("x1:login") # /api/login/
url = reverse("x1:order") # /web/login/
url = reverse("x1:auth") # /api/login/
url = reverse("x2:auth") # /web/login/
两个扩展:
namespace需要设置app_name
urlpatterns = [
path('api/', include("apps.api.urls", namespace='x1')),
]
# 在指定APP的urls内定义appname
from django.urls import path, re_path
from apps.api import views
# 很多功能,很多URL
urlpatterns = [
path('login/', views.login, name="login"),
path('auth/', views.auth, name='auth'),
]
app_name = "api"
手动分发
手动分发 不会去 找namespace
赠送:
在settings内设置
APPEND_SLASH = True
path('login/', views.login),
http://127.0.0.1:8000/login/ 成功
http://127.0.0.1:8000/login django,重定向301
http://127.0.0.1:8000/login/ 成功
path('login', views.login),
http://127.0.0.1:8000/login 成功
http://127.0.0.1:8000/login
http://127.0.0.1:8000/login/ 失败
APPEND_SLASH = False
path('login/', views.login),
http://127.0.0.1:8000/login/ 成功
http://127.0.0.1:8000/login 失败
path('login', views.login),
http://127.0.0.1:8000/login/ 失败
http://127.0.0.1:8000/login 成功
常见 & 必须掌握
差点意思
补充小知识点(与django路由无关,看源码时有关)
关于 partial
def _xx(a1, a2):
return a1 + a2
data = _xx(11, 22)
print(data)
from functools import partial
def _xx(a1, a2):
return a1 + a2
yy = partial(_xx, a2=100)
data = yy(2)
print(data)