一、urls硬编码

在反向解析和命名空间之前我们先来说说URLS硬编码,用django 开发应用的时候,可以完全是在urls.py 中硬编码配置地址,在views.py中HttpResponseRedirect()也是硬编码转向地址,当然在template 中也是一样了,这样带来一个问题,如果在urls.py 中修改了某个页面的地址(也就是说更改路由系统中对应的路由分发),那么所有的地方(views.py和template中)都要修改。问题出在硬编码,紧耦合使得在大量的模板中修改 URLs 成为富有挑战性的项目。来看下面的模板文件index.html中,我们到的链接硬编码成这样子:

<li><a href="/goods/index/">url硬编码</a></li>

如果使用软编码之后,无论怎么更改路由系统中的路由分发,只有对应的namespace与name属性值不变,就不必修改在views.py和template中的url,也就是说

<li><a href="{% url "good:index" %}">url软编码</a></li>

在templates中更改为软编码之后,其实在templates,index.html文件生成的时候,仍然是

<li><a href="/goods/index/">url软编码</a></li>

二、URL的反向解析

在使用Django 项目时,一个常见的需求是获得URL 的最终形式,以用于嵌入到生成的内容中(视图中和显示给用户的URL等)或者用于处理服务器端的导航(重定向等)。
人们强烈希望不要硬编码这些URL(费力、不可扩展且容易产生错误)或者设计一种与URLconf 毫不相关的专门的URL 生成机制,因为这样容易导致一定程度上产生过期的URL。

获取一个URL 最开始想到的信息是处理它视图的标识(例如名字),查找正确的URL 的其它必要的信息有视图参数的类型(位置参数、关键字参数)和值。
Django 提供一个办法是让URL 映射是URL 设计唯一的地方。你填充你的URLconf,然后可以双向使用它:
1、根据用户/浏览器发起的URL 请求,它调用正确的Django 视图,并从URL 中提取它的参数需要的值。
2、根据Django 视图的标识和将要传递给它的参数的值,获取与之关联的URL。

第一种方式是我们常说的根据地址定位URL。

第二种方式叫做反向解析URL、反向URL 匹配、反向URL 查询或者简单的URL 反查

在需要URL 的地方,对于不同层级,Django 提供不同的工具用于URL 反查:
1、在模板中:使用url 模板标签。
2、在Python 代码中:使用 django.core.urlresolvers.reverse() 函数。
3、在更高层的与处理Django 模型实例相关的代码中:使用 get_absolute_url() 方法。

1、命名空间:

URL 命名空间允许你反查到唯一的命名URL 模式,即使不同的应用使用相同的URL 名称。第三方应用始终使用带命名空间的URL 是一个很好的实践。类似地,它还允许你在一个应用有多个实例部署的情况下反查URL。换句话讲,因为一个应用的多个实例共享相同的命名URL,命名空间将提供一种区分这些命名URL 的方法。

一个URL 命名空间有两个部分,它们都是字符串:

<1>、应用命名空间:

它表示正在部署的应用的名称。一个应用的每个实例具有相同的应用命名空间。例如,可以预见Django 的管理站点的应用命名空间是' admin '。

<2>、实例命名空间:

它表示应用的一个特定的实例。实例的命名空间在你的全部项目中应该是唯一的。但是,一个实例的命名空间可以和应用的命名空间相同。它用于表示一个应用的默认实例。例如,Django 管理站点实例具有一个默认的实例命名空间'admin'。 URL的命名空间使用':' 操作符指定。例如,管理站点应用的主页使用' admin:index '。它表示' admin ' 的一个命名空间和' index ' 的一个命名URL.

# include函数的API
include(arg, namespace=None, app_name=None)
# namespace设置实例命名空间,app_name设置应用命名空间
# 不能只设置app_name,否则会报错,以下是报错的源码
if app_name and not namespace:
raise ValueError('Must specify a namespace if specifying app_name.')

一般来说,同一应用下的不同实例应该具有相同的应用命名空间,但是,这并不意味着不同应用可以使用相同的实例命名空间,因为实例命名空间在你所有项目中都是唯一的。

问题: 另外在添加命名空间 namespace时可能会出现以下这个问题:

    'Specifying a namespace in include() without providing an app_name '
django.core.exceptions.ImproperlyConfigured: Specifying a namespace in include() without providing an app_name is not supported. Set the app_name attribute in the included module, or pass a 2-tuple containing the list of patterns and app_name instead.

解决方案为:

在对应的app应用的urls.py中添加app_name = '[应用名称]'如下

from django.conf.urls import url
from . import views app_name = 'users'
# users为当前应用的名称 urlpatterns = [
url('^$', views.index),
url('^(\d+)/$', views.detail),
]

三、url反向解析实例

在我们的django项目中通常App,目录结构就可以如下daily_fresh_demo

daily_fresh_demo 
 |----daily_fresh_demo
    |----__init__.py
    |----settings.py
    |----urls.py
    |----wsgi.py
  |----df_cart #对商品购物车管理
|---- migrations # 迁移文件目录
|---- admin.py
|---- apps.py
|---- models.py
|---- test.py
|---- urls.py
|---- views.py
|---- __init__.py
  |----df_goods  #商品以及后台管理
...
  |----df_user #用户管理
...
  |----df_order #订单管理
...
  |----templates
     |index.html

1、路由分发:


daily_fresh_demo/daily_fresh_demo/urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include urlpatterns = [
path('admin/', admin.site.urls),
url(r'^goods/', include('df_goods.urls', namespace='df_goods')), # 添加实例命名空间
url(r'^user/', include('df_user.urls', namespace='df_user')),
url(r'^cart/', include('df_cart.urls', namespace='df_cart')),
url(r'^order/', include('df_order.urls', namespace='df_order')),
]

根据路由分发到各个相应的app中。并添加实例命名空间

2、子路由


daily_fresh_demo/df_goods/urls.py
from django.conf.urls import url

from . import views

app_name = 'df_goods' # 应用命名空间

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

df_goods中的路由,添加应用命名空间。并在url函数中添加name属性。

3、视图函数

daily_fresh_demo/df_goods/views.py

from django.shortcuts import render, reverse

def index(request):
print(reverse("df_goods:index")) # 利用reverse函数反向解析url
  # 打印结果为/goods/index/
return render(request, 'index.html')

4、静态文件 index.html

daily_fresh_demo/templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<a href="/goods/index">硬链接</a>
<a href="{% url "df_goods:index" %}">软链接</a>
</body>
</html>

5、结果

静态文件中index.html的url解析结果如下

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<a href="/goods/index">硬链接</a>
<a href="/goods/index/">软链接</a> # 软编码通过解析后得到的结果与硬编码一致
</body>
</html>

总结:这样一来通过命名空间,无论在templates文件中有多庞大的url地址映射,只要使用url软编码,在更改路由系统的时候,都能自动生成。而如果使用硬链接硬编码 ,就只能在views.py和静态文件中逐个修改url地址,不仅耗费时间,更容易产生错误。

Django-url反向解析和命名空间的更多相关文章

  1. python 之 Django框架(路由系统、include、命名URL和URL反向解析、命名空间模式)

    12.36 Django的路由系统 基本格式: from django.conf.urls import url urlpatterns = [ url(正则表达式, views视图函数,参数,别名) ...

  2. Django url反向解析与路由分发名称空间

    url反向解析 url.py from django.conf.urls import url from django.contrib import admin from app01 import v ...

  3. django之反向解析和命名空间

    背景:当我们页面中存放的请求路径与url文件中的url一致时,如果url改了是不是所有的请求路径都要跟着改?显然不现实,这里我们就要用到反向解析. 如下图所示,输入url后会跳转到登录页面,输入用户名 ...

  4. Django url配置 正则表达式详解 分组命名匹配 命名URL 别名 和URL反向解析 命名空间模式

    Django基础二之URL路由系统 本节目录 一 URL配置 二 正则表达式详解 三 分组命名匹配 四 命名URL(别名)和URL反向解析 五 命名空间模式 一 URL配置 Django 1.11版本 ...

  5. Django路由系统-URL命名&URL反向解析

    命名URL和URL反向解析 前言 起始样式,HTML中的href是写死的,不能更改,如下示例代码: # urls中 urlpatterns = [ url(r'^admin/', admin.site ...

  6. django的url反向解析

    目的:防止页面中url地址改变,其他与这个URL地址有关联的都要改,减少耦合度 使用:主要分为在html中和视图函数中的使用 HTML中的使用: 如果我们在项目的url文件中通过include导入了应 ...

  7. Django学习笔记之Django的url反向解析

    0x00 URL反向解析和三种不同的反向解析方式 Django中提供了关于URL的映射的解决方案,可以做两个方向的使用: 1.普通解析过程:由客户端的浏览器发起一个url请求,Django根据URL解 ...

  8. django命名url与url反向解析

    1.在urls.py路由中指定别名 2.在views.py视图文件中导入from django.shortcuts import render, redirect, reverse 3.也可从这里导入 ...

  9. Django之url反向解析

    在urls.py文件中,在进行url映射时,为请求的url命个名,以便在模板页面或者views.py视图中可以进行反向解析,同时在修改了url映射的请求路径,名称不变的情况下,不再修改模板页面或者视图 ...

随机推荐

  1. [Swift]优先队列PriorityQueue(自定义数据结构)

    优先队列[priority queue] 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除. 优先队列特点:在优先队列中,元素被赋予优先级. 当访问元素时,具有最高优先级的元素最先 ...

  2. 谈一谈对MySQL InnoDB的认识及数据库事物处理的隔离级别

    介绍: InnoDB引擎是MySQL数据库的一个重要的存储引擎,和其他存储引擎相比,InnoDB引擎的优点是支持兼容ACID的事务(类似于PostgreSQL),以及参数完整性(有外键)等.现在Inn ...

  3. 《Python编程从入门到实践》--- 学习过程笔记(2)变量和简单数据类型

    一.变量无需声明 二.变量命名规则 (1)变量名只能包括字母.数字和下划线: (2)变量名不能包含空格: (3)变量名不能使用Python关键字和函数名(保留字不可以做变量名); (4)简短易懂,清晰 ...

  4. POJ 2771

    #include <iostream> #include <string> #define MAXN 505 using namespace std; int _m[MAXN] ...

  5. Vue2.5开发去哪儿网App 第五章笔记 下

    1. 多个元素或组件的过渡 多个元素的过渡: <style> .v-enter,.v-leace-to{ opacity: 0; } .v-enter-active,.v-leave-ac ...

  6. (转)explain、db2exfmt 命令的使用:文本输出执行计划

    原文:http://blog.51cto.com/freebile/1068610 db2有图形执行计划显示工具,如果没有图形环境,如unix主机,可以生成文本的文件来显示执行计划1.如果第一次执行, ...

  7. SQL Server性能优化(7)理解数据库文件组织

    一.基本单位"页"     SQL Server是用8KB的页来存储数据.物理I/O操作也是在页级执行.页的种类有很多,具体参考(MSDN).我们关注更多的是数据页的结构,包括三部 ...

  8. Attr的visitNewClass()方法解读

    在visitNewClass()方法中有如下注释: We are seeing an anonymous class instance creation.In this case, the class ...

  9. C#基础篇九OOP属性结构枚举

    1.设计一个Ticket类,有一个距离属性(本属性只读,在构造方法中赋值),不能为负数,有一个价格属性,价格属性只读,并且根据距离计算价格(1元/公里):-----------0-100公里 票价不打 ...

  10. 31-hadoop-hbase-mapreduce操作hbase

    有一些大的文件,需要存入HBase中,其思想是先把文件传到HDFS上,利用map阶段读取<key,value>对,可在reduce把这些键值对上传到HBase中. HbaseMapper: ...