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. BUAA软工第一次作业-热身

    第一次作业-热身 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) (北京航空航天大学 - 计算机学院) 这个作业的要求在哪里 第一次作业-热身作业(阅读) 我在这个课程 ...

  2. Android问题:ScrollView默认位置不是最顶部最全解决方案

    描述: Scrollview里面嵌套了一个listview ,这是开发中最寻常的一种布局,遇到的问题是:在这个Scrollview页面默认的起始位置不是最顶部,而是listview的底部. 原因: 在 ...

  3. 十五、web中处理乱码问题总结

    一.jsp变成之道---中文乱码 jsp在转换为Servlet的过程经过三次编码转化: 转自  http://www.cnblogs.com/chenssy/p/4235191.html 二.java ...

  4. JS动态获取 Url 参数

    此操作主要用于动态 ajax 请求 1.首先封装一个函数 GetRequest(),能动态获取到 url 问号"?"后的所有参数 , function GetRequest() { ...

  5. 通过CrawlSpider对招聘网站进行整站爬取(拉勾网实战)

    爬虫首先要明确自己要爬取的网站以及内容 进入拉勾网的网站然后看看想要爬取什么内容职位,薪资,城市,经验要求学历要求,全职或者兼职职位诱惑,职位描述提取公司的名称 以及 在拉勾网的url等等 然后在na ...

  6. rapid-generator JAVA代码生成器

    有感于马上要做个比较大的业务系统,想到那无止境的增删改查.粘贴复制,顿时脑后升起一阵凉风.于是想到个找或者写一个Java代码的生成器,这样在正常开发进度下,也能余下更多的时间去做些别的事情. 闲话少说 ...

  7. Python集合语法

    a = {1,2,3,4,5,6,7,8,"aa","2"}    b = {2,3,4,5,6,7,8,9,99,7,6,6} v = a.intersect ...

  8. query.locate过个过滤参数

    需要引用Variants locate( 'typeid;name',vararrayof([key1,key2]),[]);

  9. MQTT 协议学习:003-MQTT通信流程介绍

    背景 有关博文:通信报文的构成 . 上一讲说到可变头与消息体要结合不同的报文类型才能够进行分析(实际上,官方的文档的介绍顺序就是这样的) 那么,我们就来具体看看有关的报文类型. 在此之前 我们捋一捋完 ...

  10. Zabbix——自动监控

    zabbix简介 zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案. zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以让系统管 ...