Django框架 之 URLconf

浏览目录

  • URL

    • 摘要
    • Django如何处理一个请求
  • 反向解析URL
    • name模式
    • namespace模式

一、URL

1、摘要

我们要在Django项目中为应用程序设计URL,我们可以创建一个名为URLconf(通常为urls.py)的Python模块。
这个模块是纯Python代码,是一个简单的正则表达式到Python函数(视图)之间的映射。

这种映射关系可以很简短也可以很复杂。它还可以引用其他的映射关系。

2、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、分组和命名分组不能同时使用。

请求URL:

1
http://127.0.0.1:8000/kwargs_test/123/abc/
1
url(r'^kwargs_test/(\d+)/(?P<name>\w+)/', views.kwargs_test),  

视图:

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

输出:

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

注:位置参数取不到值。  

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

请求URL:

1
http://127.0.0.1:8000/kwargs_test/123/abc/
1
url(r'^kwargs_test/(\d+)/(?P<name>\w+)/', views.kwargs_test, {"name1""yaya"}),  

视图:

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

输出:

1
() {'name''abc''name1''yaya'}  

注:分组和命名分组不能同时使用,位置参数取不到值,关键字相同,则全输出,否则覆盖正则表达式中命名分组捕获的值。

小总结 

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

  1. 在正则匹配模式中使用分组模式从请求的URL中捕获参数并以位置参数的形式传递给视图。

  2. 在正则匹配模式中使用命名分组模式从请求的URL中捕获参数并以关键字参数的形式传递给视图。

  3. 通过给django.conf.urls.url()传递参数。 

二、反向解析URL

在我们的Django项目中,我们经常会遇到要在视图中返回一个重定向到具体URL的响应,或者要将具体的URL地址嵌入到HTML页面中(如:a标签的href属性等)的情况,Django框架充分考虑了这种需求,所以提供了工具来反向解析(推导)出具体的URL。

1、name模式

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

1.1、普通情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# urls.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中
<a href="{% url 'students' %}">点击查看所有学生信息</a>

1.2、URL中需要位置参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# urls.py
urlpatterns = [
    # 为匹配模式起别名,并且正则表达式中有分组匹配
    url(r'^student/(\d+)', views.student_detail, name="student_detail"),
]
 
# 视图views.py中通过使用django.urls.reverse根据上面的别名反向推导出URL
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中
<a href="{% url 'student_detail' 1 %}">点击查看学生详细信息</a>

1.3、URL中需要关键字参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# urls.py
urlpatterns = [
    # 为匹配模式起别名,并且正则表达式中有分组匹配
    url(r'^student/(?P<num>\d+)', views.student_detail, name="student_detail"),
]
 
# 视图views.py中通过使用django.urls.reverse根据上面的别名反向推导出URL
from django.urls import reverse
def add_student(request):
    if request.method == "POST":
        # 根据别名和位置参数反向推导出具体的URL,避免出现硬编码URL的情况。
        # 得到URL:/student/10/
        url = reverse("student_detail", kwargs={"num"10})
        return redirect(url)
 
# HTML中
<a href="{% url 'student_detail' num=10 %}">点击查看学生详细信息</a>  

2、namespace模式

我们的项目比较庞大,其URL可能成百上千,不可避免的会出现别名重复的情况。这个时候就需要使用namespace了,我们可以为不同的urlpatterns设置一个namespace(命名空间),这样在不同的命名空间下即使别名相同,还是可以通过namespace来区分不同的URL匹配模式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 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"),
]
 
# 视图views.py中
def index(request):
    # 通过 namespce:name 的方式来反向推导出准确的URL
    url = reverse("shanghai:index")
 
# HTML中
<a href="{% url 'shanghai:index' %}">上海分公司首页</a>

app_name

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

1
2
3
4
5
6
# 在上面示例的app01/urls.py文件中:
 
app_name = "beijing"
urlpatterns = [
    url(r'^index/$', views.index, name="index"),
]

  

Django框架 之 URLconf的更多相关文章

  1. 理解django框架中的MTV与MVC模式

    1.Models:一个抽象层,用来构建和操作你的web应用中的数据,模型是你的数据的唯一的.权威的信息源.它包含你所储存数据的必要字段和行为.通常,每个模型对应数据库中唯一的一张表. from dja ...

  2. Python Django框架笔记(五):模型

    #前言部分来自Django Book (一)    前言 大多数web应用本质上: 1. 每个页面都是将数据库的数据以HTML格式进行展现. 2. 向用户提供修改数据库数据的方法.(例如:注册.发表评 ...

  3. Django框架3——模型

    Django数据库层解决的问题 在本例的视图中,使用了pymysql 类库来连接 MySQL 数据库,取回一些记录,将它们提供给模板以显示一个网页: from django.shortcuts imp ...

  4. Django框架全面讲解

    Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. ...

  5. Django 框架 基本知识

    一.什么事web框架 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支持结构,使用框架可以使我们快速开发特定的系统,简单来说,就是讲实现方式的底层结构进行封装,提供相应的 ...

  6. 第三百零四节,Django框架,urls.py模块,views.py模块,路由映射与路由分发以及逻辑处理——url控制器

    Django框架,urls.py模块,views.py模块,路由映射与路由分发以及逻辑处理——url控制器 这一节主讲url控制器 一.urls.py模块 这个模块是配置路由映射的模块,当用户访问一个 ...

  7. 框架----Django框架知识点整理

    一.cbv cbv(class-base-view) 基于类的视图 fbv(func-base-view) 基于函数的视图 a.基本演示 urlpatterns = [ url(r'^login.ht ...

  8. 第六模块:WEB框架开发 第1章·Django框架开发88~128

    88-Ajax简介 89-Ajax的简单实现 90-基于Ajax的传递数据 91-基于Ajax的登录验证 92-基于Form表单的文件上传 93-请求头之contentType 94-Ajax传递js ...

  9. 第六模块:WEB框架开发 第1章·Django框架开发1~50

    01-Django基础介绍 02-Web应用程序1 03-Web应用程序2 04-http请求协议1 05-http请求协议2 06-http协议之响应协议 07-wsgire模块1 08-wsgir ...

随机推荐

  1. 《精通.NET企业项目开发》 - 书摘精要

    (P7) 处于任何逻辑层面上的类,对于同一层面上的其他类应该是可重用的:对于在同等范围内其他所有需要该数据的类而言,提供数据的类应该是可以被调用的: (P9) 大多数企业系统都是用平台无关的技术构建的 ...

  2. git公私钥的拷贝

    1.场景 由于我换了一台电脑,为了能访问远程仓库,我就把原来电脑上的私钥和config文件拷贝过来 2.出现问题及解决方案 git clone server:xxx_service_express 报 ...

  3. mysql数据库优化。(强力推荐)

    本文转自:https://m.aliyun.com/yunqi/articles/38809 一个成熟的数据库架构并不是一开始设计就具备高可用.高伸缩等特性的,它是随着用户量的增加,基础架构才逐渐完善 ...

  4. linux下的第一个C程序及其编译方法

    #include <stdio.h> #include <stdlib.h>   int main(int argc, char ** argv) {     printf(& ...

  5. HDU1815 Building roads(二分+2-SAT)

    Problem Description Farmer John's farm has N barns, and there are some cows that live in each barn. ...

  6. tableau学习笔记—1

    第一部分 第一章 数据可视化 1.1 用数据讲故事 1.2 数据不只是数字 1.3 在数据中寻找什么(关系.模式.异常) 第二章 Tableau概述 2.1 Tableau概述 2.2 产品简介 第三 ...

  7. 什么是 PCB 的压适孔

    引用 AMOBBS 1 再举一个高成本控制的例子:有类PCB产品对孔径要求极度严格,这类孔叫压适孔,这类孔的作用类似于显卡内存条的插座,能刚刚好被元件插上,而且元件不会掉,PTH的压适孔公差要求为-0 ...

  8. Qt中int转换成QString

    (1) QString QString::number ( long n, int base = 10 ) [static] examle: long a = 48; QString s = QStr ...

  9. mysql之 Innobackupex(全备+增量)备份恢复

    MySQL的热备(物理备份)可以采取全备加增量备份的方式来减轻数据库I/O压力及系统资源的占用.增量备份主要是以全备或增量备份为基础,备份那些变更过的页面.其备份的原理是基于一个不断增长的LSN序列, ...

  10. Ant能干什么,编译?打包!

    Ant轻便,灵巧,不像Maven一般沉重. 但是,这是我之前的看法.之前一直使用Eclipse自带的编译工具进行编译,然后采用ant进行打包:但是Eclipse编译工具编译之后的jar包参数名称之类的 ...