一、 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 %}