Django URL name 详解

利用Django开发网站,可以设计出非常优美的url规则,如果url的匹配规则(包含正则表达式)组织得比较好,view的结构就会比较清晰,比较容易维护。

Django如何处理一个请求

如果用户请求一个由Django提供服务的站点,它将按照以下逻辑决定执行哪些代码:

    1. 通常不考虑中间件的情况下,Django将会确定要使用的根URLconf模块。
    2. Django加载该Python模块并查找变量--urlpatterns,这个变量应该是一个由django.conf.urls.url()实例组成的列表。
    3. Django按照顺序遍历每一个URL模式,并停在与本次请求的URL匹配的第一个URL模式。
    4. 一旦一个正则表达式匹配上用户请求的URL,Django就会导入并调用给定的视图,该视图是一个简单的Python函数(或基于类的视图)。
      该视图将被传入以下参数:
      • 一个请求示例--request
      • 正则表达式中使用分组捕获的值将作为位置参数传递给视图。
      • 正则表达式中的命名分组捕获的值将会以关键字方式传递给视图,但是它可以被直接传参方式覆盖。
    5. 如果没有正则表达式匹配或者在此过程中发生了异常,Django都会调用适当的错误处理视图。

1 .定死的写法

urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views urlpatterns = [
url(r'^login/', views.login),
]

views.py

def login(request):
return HttpResponse('这是定死的写法')

网页上的url框

http://127.0.0.1:8000/login/

2 .正则表达式--位置传参(分组)

urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views urlpatterns = [
url(r'^location/(\d+)', views.location),
] 

views.py

def location(request,arg):
return HttpResponse('这是位置参数')

网页上的url框

http://127.0.0.1:8000/location/1      1指的是arg 是任意的数

3 .正则表达式--关键字传参(命名分组)

urls.py

url(r'^keyword/(?P<name>\w+)', views.keyword),

views.py

def keyword(request, name):
return HttpResponse('这是关键字传数')

网页上的url框

http://127.0.0.1:8000/keyword/xiao

4 .注意:

1. 分组和命名分组不能同时使用

网页上的url框 

http://127.0.0.1:8000/kwargs_test//abc/

url.py

url(r'^kwargs_test/(\d+)/(?P<name>\w+)/', views.kwargs_test),

views.py  

def kwargs_test(request, *args, **kwargs):
print(args, kwargs)
return HttpResponse("OK")

输出----(print)

() {'name': 'abc',}

2. django.conf.urls.url()的关键字参数会覆盖正则表达式中命名分组捕获的值

网页上的url框 

http://127.0.0.1:8000/kwargs_test/123/abc/

url.py

url(r'^kwargs_test/(\d+)/(?P<name>\w+)/', views.kwargs_test, {"name1": "Q1mi"}),

views.py  

def kwargs_test(request, *args, **kwargs):
print(args, kwargs)
return HttpResponse("OK")

输出----(print)

() {'name': 'abc', 'name1': 'Q1mi'}
这个值取决于url.py里的{"name1": "Q1mi"},要是写成{"name": "Q1mi"},结果就是
() {'name': 'Q1mi'}

  

小总结:
我们现在掌握了三种向视图函数传递参数的方法:

    1. 在正则匹配模式中使用分组模式从请求的URL中捕获参数并以位置参数的形式传递给视图。
    2. 在正则匹配模式中使用命名分组模式从请求的URL中捕获参数并以关键字参数的形式传递给视图。
    3. 通过给django.conf.urls.url()传递参数

反向解析URL

在我们的Django项目中,我们经常会遇到要在视图中返回一个重定向到具体URL的响应,或者要将具体的URL地址嵌入到HTML页面中(如:a标签的href属性等)的情况。

我们之前通常都会选择硬编码(写死)的方式来实现类似上述的需求,但是这并不是最优的解决办法。
例如:
在视图函数中

def add_student(request):
if request.method == "POST":
...
return redirect("/student_list/") # 将URL硬编码到视图中
...

在模板文件的HTML文件中:

<a href="/student_list/">点击查看所有学生信息</a>

Django框架充分考虑了这种需求,所以提供了工具来反向解析(推导)出具体的URL  

name模式

在Django的URLconf中,我们可以通过给匹配模式起别名,然后我们可以通过别名来反向推导出具体的URL

url.py

urlpatterns = [
url(r'^student_list/', views.student_list, name="students"), # 为匹配模式起别名
...
]

views.py

通过使用django.urls.reverse根据上面的别名反向推导出URL 

# 引入 
from django.urls import reverse
def add_student(request):
if request.method == "POST":
...
# 根据别名反向推导出具体的URL,避免出现硬编码URL的情况。
url = reverse("students") # 得到URL: /student_list/
return redirect(url)
...

在模板语言的HTML文件中,使用下面的语法来反向推导出URL 

<a href="{% url 'students' %}">点击查看所有学生信息</a>

问:当我们的匹配模式中的正则表达式有分组或命名分组的时候该怎么办呢?也就是我们仅仅通过别名无法推导出具体的URL时,该怎么办呢?
答:我们可以在反向推导URL的时候传递URL中需要的参数

URL中需要位置参数

urls.py

urlpatterns = [
# 为匹配模式起别名,并且正则表达式中有分组匹配
url(r'^student/(\d+)', views.student_detail, name="student_detail"),
...
]

views.py

from django.urls import reverse
def add_student(request):
if request.method == "POST":
...
# 根据别名和位置参数反向推导出具体的URL,避免出现硬编码URL的情况。
url = reverse("student_detail", args=(1,)) # 得到URL:/student/1/
return redirect(url)

在模板语言的HTML文件中,使用下面的语法来反向推导出URL

<a href="{% url 'student_detail' 1 %}">点击查看学生详细信息</a> 

URL中需要关键字参数

urls.py

urlpatterns = [
# 为匹配模式起别名,并且正则表达式中有分组匹配
url(r'^student/(?P<num>\d+)', views.student_detail, name="student_detail"),
...
]

views.py

from django.urls import reverse
def add_student(request):
if request.method == "POST":
...
# 根据别名和位置参数反向推导出具体的URL,避免出现硬编码URL的情况。
url = reverse("student_detail", kwargs={"num": 10}) # 得到URL:/student/10/
return redirect(url)
...

在模板语言的HTML文件中,使用下面的语法来反向推导出URL  

<a href="{% url 'student_detail' num=10 %}">点击查看学生详细信息</a> 

namespace模式

我们可以为每个URL的匹配模式设置一个别名,然后通过别名来反向推导出URL。这样的设置在小型项目也就是URL比较少的情况下是完全够用的。
但是一旦我们的项目比较庞大,其URL可能成百上千,不可避免的会出现别名重复的情况。

这个时候就需要使用namespace了,我们可以为不同的urlpatterns设置一个namespace(命名空间),这样在不同的命名空间下即使别名相同,还是可以通过namespace来区分不同的URL匹配模式

urls.py

urlpatterns = [
...
# 为app01.urls设置命名空间名:beijing
url(r'^beijing/', include("app01.urls", namespace="beijing")),
# 为app02.urls设置命名空间名:shanghai
url(r'^shanghai/', include("app02.urls", namespace="shanghai")),
...
]

app01/urls.py

urlpatterns = [
# app01/urls.py中有一个别名为index的匹配模式
url(r'^index/$', views.index, name="index"),
]

app02/urls.py  

urlpatterns = [
# app02/urls.py中也有一个别名为index的匹配模式
url(r'^index/$', views.index, name="index"),
]

现在我们就可以通过namespace来区分上面两个别名为index的匹配模式来反向推导出准确的URL了  

views.py

def index(request):
# 通过 namespce:name 的方式来反向推导出准确的URL
url = reverse("shanghai:index")
...

在模板语言的HTML中

<a href="{% url 'shanghai:index' %}">上海分公司首页</a>

  

也可以通过在app/urls.py中定义app_name来设置app级别的namespace

例如:
在上面示例的app01/urls.py文件中

app_name = "beijing"
urlpatterns = [
url(r'^index/$', views.index, name="index"),
...
]

在这种情况下反向推导URL的语法同上  

第五篇Django URL name 详解的更多相关文章

  1. Django URL name详解

    我们基于上一节的代码来开始这一节的内容. 上节源代码:zqxt_views(django 1.4 - django 1.10).zip [更新于 2016-09-06 00:13:23] 1. 打开 ...

  2. Django url()函数详解

    url()函数看起来的格式象: url(r^/account/$', views.index, name=index) ,它可以接收四个参数,分别是两个必选参数: regex . view 和两个可选 ...

  3. Django入门基础详解

    本次使用django版本2.1.2 安装django 安装最新版本 pip install django 安装指定版本 pip install django==1.10.1 查看本机django版本 ...

  4. 《手把手教你》系列基础篇(九十六)-java+ selenium自动化测试-框架之设计篇-跨浏览器(详解教程)

    1.简介 从这一篇开始介绍和分享Java+Selenium+POM的简单自动化测试框架设计.第一个设计点,就是支持跨浏览器测试. 宏哥自己认为的支持跨浏览器测试就是:同一个测试用例,支持用不同浏览器去 ...

  5. [五]基础数据类型之Short详解

      Short 基本数据类型short  的包装类 Short 类型的对象包含一个 short 类型的字段      原文地址:[五]基础数据类型之Short详解   属性简介   值为  215-1 ...

  6. URL组成部分详解

    URL组成部分详解 URL是Uniform Resource Locator的简写,统一资源定位符. 一个URL是由以下几部分组成的: scheme://host:port/path/?query-s ...

  7. SaltStack 入门到精通第三篇:Salt-Minion配置文件详解

    SaltStack 入门到精通第三篇:Salt-Minion配置文件详解 作者:ArlenJ  发布日期:2014-06-09 17:52:16   ##### 主要配置设置 ##### 配置 默认值 ...

  8. SaltStack 入门到精通第二篇:Salt-master配置文件详解

    SaltStack 入门到精通第二篇:Salt-master配置文件详解     转自(coocla):http://blog.coocla.org/301.html 原本想要重新翻译salt-mas ...

  9. “全栈2019”Java异常第十五章:异常链详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

随机推荐

  1. Vue 项目开发

    目录 Vue 项目开发 项目目录结构解析 入口文件 main.js (项目入口) 根组件 app.vue index.html 文件入口 router 路由 components 子组件 项目初始化 ...

  2. EJS 高效的 JavaScript 模板引擎

    什么是 EJS? "E" 代表 "effective",即[高效].EJS 是一套简单的模板语言,帮你利用普通的 JavaScript 代码生成 HTML 页面 ...

  3. vue的高级使用技巧

    全局组件注册 一般组件应用弊端,比较笨拙繁琐低效,比如我们写了一些组件,需要引用上的时候就通过import导入,那如果是高频繁需要使用的组件,则需要在每个使用的时候都需要引入并注册 假设现在有两个组件

  4. 嵊州普及Day3T2

    题意:对于n数列的全排列,有多少种可能,是每项前缀和不能整除3.输出可能性%1000000000037. 思路:全部模三,剩余1.2.0,1.2可这样排:1.1.2.1.2.1.2.……2或2.2.1 ...

  5. dotnet-千星项目OpenAuthNet基于NetCore21的快速开发框架

    下载

  6. ie brower 点击用默认浏览器打开链接

    <script> function GetCurrentJumpUrl(){ var eleLink = document.getElementById('adLink'); if(ele ...

  7. jmeter之http请求用csv读取中文乱码

    jmeter3.2版本中CSV Data Set Config从本地读取静态文件的时候,遇到中文乱码的解决方式如下: CSV Data Set Config设置 http请求数据显示乱码 把txt文档 ...

  8. 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:接口的基本实现

    interface A{ // 定义接口A public static final String AUTHOR = "李兴华" ; // 全局常量 public abstract ...

  9. POJ 3669 Meteor Shower BFS求最小时间

    Meteor Shower Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 31358   Accepted: 8064 De ...

  10. Lua生成比较理想的随机数的方法

    lua需要生成随机数的需求也是很常见的,为了生成看起来更随机的数字,我们需要注意以下几点 我们也需要给随机数设置随机数种子:math.randomseed(xx) lua对随机数种子也是有一定要求的: ...