Django基础 - 09路由URL控制与解析

发布时间 2023-04-16 20:49:15作者: Kingdomer

 

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

 

点击订单后, 页面跳转到 /order/list2/xa/1001 页面 

 

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