Django中路由的名称空间和反向解析,reverse ,reverse_lazy 等反向解析函数的用法,以及路由命名空间和反向解析传参的解析,用例

文章介绍了Django中路由的命名和反向解析机制,包括基础命名、反向解析函数如reverse、reverse_lazy和resolve_url的使用。通过命名空间解决多App路由冲突问题,并展示了在视图和HTML模板中如何传参。同时,文章对比了reverse、reverse_lazy和resolve_url的区别和应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Django中路由的名称空间和反向解析,reverse ,reverse_lazy 等反向解析函数的用法,以及路由命名空间和反向解析传参的解析,用例。

项目结构:

在这里插入图片描述

1. 路由的基础命名(不附带命名空间)

在对于单个App进行路由定义的时候,可能一个urls.py文件的定义就足够了我们的使用,但是对于多个App,我们可能通过 include方法,生成了多个子路由,通过每个App内单独的urls.py进行二次管理,所以此时,我们可以对路由进行命名,方便于我们对路由的快速调用。

通过path(name参数)我们可以快捷的路由进行命名。

项目主文件夹/urls.py

from django.urls import path,include

urlpatterns = [
    path("user/", include('user.urls')), # 路由分发到user.urls中
]

user/urls.py

from django.urls import path, include,re_path
import user.views

urlpatterns = [
    path("userlist/", user.views.user_list, name='userlist'), # 设置name为userlist
    re_path(r"userdetail/(?P<uid>\d*)", user.views.user_detail, name='userdetail'), # 设置name为userdetail
]

此时我们通过name的设置,已经让路由有了更加简单的"别名",我们可以方便的使用"别名"去获取他的Url值。

2. 反向解析基础

2.1 通过Python方法进行反向解析

反向解析:顾名思义,通过别名,解析出来Url的原值

反向解析的用途

eg: 现在有很多很多个路由,几百个不同的路由,我们在访问其中一个路由的时候,需要让他跳转到另一个路由,那几百个路由那么复杂,我们不可能快读的找到对应的链接值,但是我们可以通过起的别名,反向解析出来URL,便于我们使用。

在Django中的反向解析一般有这几种:

  1. reverse 方法反向解析
  2. reverse_lazy 方法反向解析
  3. resolve_url 方法反向解析
  4. redirect 反向解析并重定向
  5. Django-HTML模板语法中反向解析动态生成Url
# 在1.路由的基础命名中,我们定义了 user/userlist/ 的 name = 'userlist'
# 此时我们便可以通过调用reverse /reverse_lazy /resolve_url 传入"userlist" 获取到user/userlist/的值

#################

view.py

#################
from django.shortcuts import render, reverse, redirect,resolve_url # 导入包
from django.urls import reverse_lazy # reverse_lazy只在django.urls中存在,但是reverse, resolve_url在shortcuts和urls中都存在


def user_list(request):
    user_list = User.objects.all()
    return render(request, 'user_list.html', {"user_list": user_list})


def user_detail(request, uid):
    print(request.resolver_match.namespace)
    -> userdetail
    # request.resolver_match.namespace 用于获取当前访问的路由的名称空间
    
    print(reverse('userlist', )) # 获取 别名=userlist的原URL
    -> /user/userlist/
    print(reverse_lazy('userlist')) # reverse_lazy返回与reverse一样(一般在类视图使用,见后续解释)
    -> /user/userlist/
    print(resolve_url("userlist")) # resolve_url 不仅仅能返回 别名对应的Url 
    -> /user/userlist/
    print(resolve_url(user_list)) # 还可以通过传入视图方法/视图类进行返回
    -> /user/userlist/
    if not uid:
        return redirect('userlist') # 重定向到 别名userlist对应的路由
    user_info = User.objects.get(pk=uid)
    return render(request, "user_detail.html", {"user_info": user_info})

但是,要注意,当前对Url进行的别名命名,其实都是 全局范围 生效的命名

也就是说,例如你在App1中定义了userlist这个链接,你就不能在App2中再起userlist,不然就会造成冲突!

所以这里我们需要引出命名空间的概念

3. 路由命名空间

上面的路由基础命名,使用的名称空间都是全局的,这就导致了,我们不同App中不能够使用相同的名称

而Django为了方便区分,于是在命名的基础上,增加了命名空间的相关参数

项目主文件夹/ urls.py

# 命名空间主要针对于上层的命名重复问题,所以首先我们修改 项目主文件夹/ urls.py
from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path("admin/", admin.site.urls),
    path("user/", include('user.urls',namespace='user')), 
    # 设置user/域名下的所有的路由的命名名称空间都在user空间中
]

user/urls.py (App下的urls)

from django.urls import path, include,re_path
import user.views

app_name = 'user' # 设置该urls的名称空间为user,此时下方定义的path都会在user名称空间中
urlpatterns = [
    path("userlist/", user.views.user_list, name='userlist'), # 设置名称为 userlist
    re_path(r"userdetail/(?P<uid>\d*)", user.views.user_detail, name='userdetail'), # 设置名称为userdetail
]

## 这里注意,虽然我们设置了名称为userlist,但是由于userlist在user的命名空间下
## 所以在实际调用过程中,user的名称实际为: user:userlist 
## 格式: [name:namespace]

views.py

from django.shortcuts import render, reverse, redirect,resolve_url

def user_detail(request, uid):
    print(request.resolver_match.view_name)
    -> user:userdetail
    print(reverse('user:userlist', )) 
    -> /user/userlist/
    print(reverse_lazy('user:userlist')) 
    -> /user/userlist/
    if not uid:
        print(f'重定向')
        return redirect('user:userdetail',uid=2) 
    user_info = User.objects.get(pk=uid)
    return render(request, "user_detail.html", {"user_info": user_info})

需要注意的是,当我们使用了命名空间对某个路由进行命名后,它的名字将不在全局名称空间中,所以我们命名后

可以使用user:userlist 来反向解析,但是不可以直接使用 userlist进行解析

4. 反向解析传参

4.1 函数反向解析传参

reverse,reverse_lazy ,resolve_url,redirect的反向解析都支持传参

# 例如我们定义了一个路由
re_path(r"userdetail/(?P<uid>\d*)", user.views.user_detail, name='userdetail')
# userdetail/<uid> -> uid参数将传入user.views.user_detail
# 此时我们如果反向解析到user.views.user_detail,那也需要传递参数

# 例如reverse:
reverse('user:userdetail',uid=10) # 关键字参数设置uid=10
redirect('user:userdetail',2) # 位置参数设置uid=2
redirect('user:userdetail',kwargs={"uid":2}) # kwargs传参

4.2 HTML模板语法反向解析传参

# 语法格式
## 不传参格式
{% url "Url名称空间:Url别名" %}
## 传参格式
{% url "Url名称空间:Url别名" 参数1 参数2%} # 不同参数之间有空格!!
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户列表</title>
</head>
<body>
    <h2>用户列表</h2>
    <ul>
        {% for user in user_list %} // user_list由Django - ORM返回
            <li>
                <a href="{% url "user:userdetail" user.id %}">姓名:{{ user.name }}</a> //反向解析userdetail并传入uid参数
            </li>
        {% endfor %}
    </ul>
</body>
</html>

5. 三种反向解析函数的区别,及用途

5.1 reverse()

  • 接受一个 URL 名称作为参数,会根据该名称解析出对应的 URL,并返回解析后的 URL 字符串。
  • 使用 reverse() 需要保证 Django 的 URL 配置已经加载,并且解析过程能够找到对应的 URL。
  • 适用于在视图函数、模板等地方进行 URL 反转。

5.2 reverse_lazy()

  • reverse_lazy() 是 Django 的一个实用函数,类似于 reverse(),但它返回的是一个延迟解析的对象
  • 它接受一个 URL 名称作为参数,会根据该名称延迟解析出对应的 URL,并返回一个代理对象。
  • reverse_lazy() 不会在初始化阶段尝试解析 URL,只有在实际访问代理对象时,才会触发 URL 解析。
  • 适用于在类视图等场景下,保证在实际访问视图时才会解析 URL,避免在启动时可能发生的错误。
  • 说白了,类视图把reverse换成这个,函数视图开发种,用reverse()就可以。

5.3 resolve_url()

  • 可以根据多种类型的参数进行解析,包括 URL 字符串、URL 名称、视图函数、类视图、对象的 get_absolute_url() 方法等。
  • 适用于在视图中构建动态链接、进行重定向等场景。
    触发 URL 解析。**
  • 适用于在类视图等场景下,保证在实际访问视图时才会解析 URL,避免在启动时可能发生的错误。
  • 说白了,类视图把reverse换成这个,函数视图开发种,用reverse()就可以。

5.3 resolve_url()

  • 可以根据多种类型的参数进行解析,包括 URL 字符串、URL 名称、视图函数、类视图、对象的 get_absolute_url() 方法等。
  • 适用于在视图中构建动态链接、进行重定向等场景。
  • resolve_url不光可以解析字符串,例如你传一个函数,他也能给你解析出来,所以更加专业,但是一般用不到。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值