一、 URL路由配置
1.1 主路由: 主程序目录下的urls.py; 对应属性ROOT_URLCONF
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', index),
# 配置子路由
# include() 导入mainapp模块下urls.py中声明的所有子路由
path('user/', include('mainapp.urls')),
path('order/', include('orderapp.urls', namespace='orderapp')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
1.2 子路由: app模块目录下的urls.py
from mainapp.views import user_list, user_list2, user_list3
urlpatterns = [
path('user', user_list),
path('user2', user_list2, name=None),
]
二、 URL配置正则匹配
2.1 精准匹配
url() 是 兼容Django1.x版本的配置; path() 是 Django2 之后的路由函数
path('list', views.order_list),
url(r'^list2$', views.order_list),

2.2 url 模糊匹配
url(r'^list2/(\w+)$',views.order_list),
访问 http://127.0.0.1:8000/order/list2/asa121
def order_list(request, order_no):
print("order_no: ", order_no)
return render(request, 'list_order.html', locals())
2.3 url()通过正则在URL路径中向View函数传参
url(r'^list2/(?P<city_code>\w+)/(?P<order_no>\d+)$', views.order_list),
def order_list(request, order_no, city_code):
print("order_no: ", order_no, ", city_code: ", city_code)
return render(request, 'list_order.html', locals())
2.4 Django2 的 path路径匹配
访问 http://127.0.0.1:8000/order/list2/qd/121
url(r'^list2/(?P<city_code>\w+)/(?P<order_no>\d+)$', views.order_list)
path('list2/<city_code>/<order_no>', views.order_list)
2.5 Django2 的 path 中使用类型转换器进行类型匹配
格式: <类型:参数名>
类型转换器: str:非空字符串 / int:0或一个正数 / slug: 任意ASCII字符 / uuid:UUID格式字符串
访问 http://127.0.0.1:8000/order/cancel/7ce31b33-c079-4d1a-b826-418803bac390
path('cancel/<uuid:order_no>', views.cancel_order)
>>> import uuid
>>> print(uuid.uuid4())
7ce31b33-c079-4d1a-b826-418803bac390
2.6 复杂路由规则匹配re_path
re_path(r'^search/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$')
re_path('search/(?P<phone>1[3-57-9][\d]{9})$', views.search, name='search'),
def search(request, phone):
return HttpResponse('hi, phone: %s' % phone)
三、反向解析
include的 namespace 和 path的 name 都在反向解析中使用, 使用 'namespace.name' 反向获取url路径
# 主路由
path('order/', include('orderapp.urls', namespace='orderapp')),
# 子路由
# 不指定app_name报错Specifying a namespace in include() without providing an app_name is not supported.
app_name = 'orderapp'
path('list2/<city_code>/<order_no>', views.order_list, name='list'),
3.1 在页面中获取路径
{% extends 'base.html' %}
{% block content %}
<h3>我的订单</h3>
<p> # 以下三种方式都正确, 位置传参(空格分隔)、 关键字传参
{# <a href="/order/list/xa/1001">订单</a>#}
{# <a href="{% url 'orderapp:list' city_code='xa' order_no=1001 %}">订单</a>#}
<a href="{% url 'orderapp:list' 'xa' 1001 %}">订单</a>
</p>
{% endblock %}

3.2 在视图函数中获取路径
在视图函数中,使用reverse()函数来反向获取url请求路径,再通过redirect或HttpResponseRedirect()重定向。
reverse() 使用args位置传参, 使用kwargs 字典类型进行传参; redirect返回的就是HttpResponseRedirect。
def query(request):
from django.urls import reverse
url = reverse('orderapp:search', args=('15799991111',))
# return HttpResponse('Hi, Query %s' % url)
# return redirect(url)
url2 = reverse(viewname='orderapp:list', kwargs=dict(city_code='bj', order_no=2931))
# return redirect(url2)
# return HttpResponseRedirect(url2)
url3 = reverse('orderapp:list', kwargs=dict(order_no=1211))
# return HttpResponseRedirect(url3)
return redirect(url3)
访问 /order/query

四、自定义错误视图
4.1 定义错误页面404.html
关闭Django DEBUG模式 DEBUG = False
{% extends 'base.html' %}
{% block content %}
<h3 style="color: red;">
Sorry, 请求的资源 {{ request_path }} 不存在!
<script>
document.write(window.location.href)
</script>
</h3>
<p>
3秒之后自动跳转到<a href="/">主页</a>
</p>
{% endblock %}

浙公网安备 33010602011771号