Django 路由层URLconf的实现


Posted in Python onDecember 30, 2019

分组

分组的目的:让服务端获得url中的具体数据,通过分组,把需要的数据按函数传参的方式传递给服务器后台

1-无名分组

若要从URL 中捕获一个值,只需要在它周围放置一对圆括号

# app01/urls.py
from django.urls import path, re_path
from app01 import views


app_name = "app01"
urlpatterns = [

  path("login/", views.login, name="Log"),
  re_path(r"articles/([0-9]{4})/([0-9]){2}/", views.articles),

]
# app01/views.py
def articles(request, year, month ):
  print(year, month)
  return HttpResponse(year+"-"+month)

2-有名分组

在更高级的用法中,可以使用命名的正则表达式组来捕获URL 中的值并以关键字 参数传递给视图。

在Python 正则表达式中,命名正则表达式组的语法是(?P<name>),其中name 是组的名称,下面是以上URLconf 使用命名组的重写。

# app01/urls.py
from django.urls import path, re_path
from app01 import views

app_name = "app01"
urlpatterns = [

  path("login/", views.login, name="Log"),
  re_path(r"articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2}/)", views.articles),
]

捕获的值作为关键字参数而不是位置参数传递给视图函数

# app01/views.py
def articles(request, month, year ):
  print(year, month)
  return HttpResponse(year+"-"+month)

分发

分发的目的:解决一个django项目中因为存在多个应用app导致project下面的urls臃肿和分配混乱的问题

分发的具体操作流程是:

step1:项目文件下的urls.py,使用include()

# project/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
  path('admin/', admin.site.urls),
  path(r"app01/", include("app01.urls")),
]

step2:app下的具体url

# app01/urls.py
from django.urls import path
from app01 import views

urlpatterns = [
  path("login/", views.login),

]

step3:视图函数render时模板路径前缀

# app01/views.py
from django.shortcuts import render
# Create your views here.

def login(request):

  return render(request, "app01/login.html")

step4:模板

# app01/templates/app01/login.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>app01_title</title>
</head>
<body>
  <h2>app01_login</h2>
  <hr>
  <form action="" method="post">
    <p>用户名 <input type="text" name="name"></p>
    <p>密码 <input type="password" name="pwd"></p>
    <p><input type="submit" value="登录"></p>
  </form>

</body>
</html>

反向解析

反向解析的目的:解决url硬编码的问题,即不能写死一个url,否则日后修改url,造成的维护成本巨大

此时可以给url命名,然后可以在视图和模板中使用url别名,反向解析出正式的url

反向解析分两种:模板中解析、视图中解析

模板中解析 <form action="{% url "Art" 12 %}" method="post">

# app01/urls.py
from django.urls import path
from app01 import views

urlpatterns = [

  path("login/", views.login, name="Log"),
  path("articles/<int:id>/", views.articles, name="Art"),  #有参

]
# app01/templates/app01/login.html
<form action="{% url "Log" %}" method="post">
  <p>用户名 <input type="text" name="name"></p>
  <p>密码 <input type="password" name="pwd"></p>
  <p><input type="submit" value="登录"></p>
</form>

<form action="{% url "Art" 12 %}" method="post">
  <p>用户名 <input type="text" name="name"></p>
  <p>密码 <input type="password" name="pwd"></p>
  <p><input type="submit" value="登录"></p>
</form>

视图中解析 reverse("Art", args=(id,))

# app01/views.py
from django.shortcuts import render
from django.urls import reverse

# Create your views here.

def login(request):
  
  print(reverse('log'))
  id=10
  print(reverse("Art", args=(id,)))
  
  return render(request, "app01/login.html")

命名空间

命名空间要配合反向解析使用,当存在多个app,url的name冲突时,需要指定该name的命名空间

# project/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
  path('admin/', admin.site.urls),
  path(r"app01/", include("app01.urls", namespace="app01")),
  path(r"app02/", include("app02.urls", namespace="app02")),
]

在django2.x中,app01/url.py需要添加 app_name = "app01"

# app01/urls.py
from django.urls import path
from app01 import views

app_name = "app01"
urlpatterns = [
  path("login/", views.login, name="Log"),

]
# app01/views.py(需要时设置)
from django.shortcuts import render
from django.urls import reverse
# Create your views here.

def login(request):
  a = reverse("app01:Log")
  print("app01:", a)
  return render(request, "app01/login.html")
# app01/templates/app01/login.html(需要时设置)
<form action="{% url "app01:Log" %}" method="post">
   <p>用户名 <input type="text" name="name"></p>
   <p>密码 <input type="password" name="pwd"></p>
   <p><input type="submit" value="登录"></p>
 </form>

转换器

对于django2.0版本以后,出现新的path() urlconf,他有两个好处:

1:url修改维护变得简单

2:url获得的参数的数据类型不再是单纯的str,在path中可以通过转换器实现参数数据类型的转换

path()中存在5个内置转化器:

=1. str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
2. int,匹配正整数,包含0。
3. slug,匹配字母、数字以及横杠、下划线组成的字符串。
4. uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
5. path,匹配任何非空字符串,包含了路径分隔符

使用方法:

step1: app01/urls.py

from django.urls import path, re_path
from app01 import views

app_name = "app01"
urlpatterns = [
  path("login/", views.login, name="Log"),
  # re_path(r"articles/(?P<year>[0-9]{4})/", views.articles),

  path("articles/<int:year>/<int:month>/", views.articles),
]

step2: app01/views.py

def articles(request, year, month):

  print(year, month)
  print(type(year))

  return HttpResponse("ok")
  • <int: year> 相当于re_path()中的 (?P[0-9]{4})
  • <> 表示有名分组,year是组名;int表示传参的数据类型是正整数(但包括0)

自定义转换器

step1: app01/my_converters.py

class YearConverter:  
  
  regex = '[0-9]{4}'  
  
  def to_python(self, value):    
    return int(value)  
  
  def to_url(self, value):    
    return '%04d' % value

step2: app01/urls.py

from django.urls import path, re_path, register_converter
from app01 import views, my_converters

register_converter(my_converters.YearConverter, 'year')
app_name = "app01"
urlpatterns = [

  path("login/", views.login, name="Log"),
  # re_path(r"articles/(?P<year>[0-9]{4})/", views.articles),
  # path("articles/<int:year>/<int:month>/", views.articles),
  
  path("books/<year:y>", views.books),
]

step3: app01/views.py

def books(request, y):

  print(y, type(y))
  return HttpResponse("ok,books")

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python利用多进程将大量数据放入有限内存的教程
Apr 01 Python
Python正则表达式教程之一:基础篇
Mar 02 Python
基于Python数据可视化利器Matplotlib,绘图入门篇,Pyplot详解
Oct 13 Python
opencv python 傅里叶变换的使用
Jul 21 Python
python如何获取当前文件夹下所有文件名详解
Jan 25 Python
对django的User模型和四种扩展/重写方法小结
Aug 17 Python
基于Python3.7.1无法导入Numpy的解决方式
Mar 09 Python
使用Django清空数据库并重新生成
Apr 03 Python
Django视图、传参和forms验证操作
Jul 15 Python
python实现二分查找算法
Sep 18 Python
Python日志打印里logging.getLogger源码分析详解
Jan 17 Python
Python 中数组和数字相乘时的注意事项说明
May 10 Python
python解析多层json操作示例
Dec 30 #Python
pytorch 求网络模型参数实例
Dec 30 #Python
利用python3 的pygame模块实现塔防游戏
Dec 30 #Python
pytorch 批次遍历数据集打印数据的例子
Dec 30 #Python
python多线程使用方法实例详解
Dec 30 #Python
Python动态声明变量赋值代码实例
Dec 30 #Python
使用pytorch实现可视化中间层的结果
Dec 30 #Python
You might like
网络资源
2006/10/09 PHP
thinkphp实现数组分页示例
2014/04/13 PHP
详解PHP的Yii框架中组件行为的属性注入和方法注入
2016/03/18 PHP
php实现的pdo公共类定义与用法示例
2017/07/19 PHP
laravel框架中控制器的创建和使用方法分析
2019/11/23 PHP
js中关于String对象的replace使用详解
2011/05/24 Javascript
window.location 对象所包含的属性
2014/10/10 Javascript
每天一篇javascript学习小结(Array数组)
2015/11/11 Javascript
jQuery设置聚焦并使光标位置在文字最后的实现方法
2016/08/02 Javascript
vue 多入口文件搭建 vue多页面搭建的实例讲解
2018/03/12 Javascript
JavaScript常见鼠标事件与用法分析
2019/01/03 Javascript
Nuxt使用Vuex的方法示例
2019/09/06 Javascript
js实现整体缩放页面适配移动端
2020/03/31 Javascript
小程序实现tab标签页
2020/11/16 Javascript
JavaScript缓动动画函数的封装方法
2020/11/25 Javascript
[03:22]DSPL第一期精彩集锦:酷炫到底!
2014/11/07 DOTA
[01:32]TI珍贵瞬间系列(一)
2020/08/26 DOTA
分析Python的Django框架的运行方式及处理流程
2015/04/08 Python
八大排序算法的Python实现
2021/01/28 Python
python类的继承实例详解
2017/03/30 Python
Python使用cx_Oracle调用Oracle存储过程的方法示例
2017/10/07 Python
python使用pycharm环境调用opencv库
2018/02/11 Python
numpy中实现二维数组按照某列、某行排序的方法
2018/04/04 Python
pytorch加载自定义网络权重的实现
2020/01/07 Python
Tensorflow累加的实现案例
2020/02/05 Python
判断Threading.start新线程是否执行完毕的实例
2020/05/02 Python
小蚁科技官方商店:YI Technology
2019/08/23 全球购物
意大利在线高尔夫商店:Online Golf
2021/03/09 全球购物
得到Class的三个过程是什么
2012/08/10 面试题
室内设计专业个人的自我评价
2013/12/18 职场文书
基层工作经历证明
2014/01/13 职场文书
学校运动会加油词
2015/07/18 职场文书
新员工实习期个人工作总结
2015/10/15 职场文书
python使用tkinter实现透明窗体上绘制随机出现的小球(实例代码)
2021/05/17 Python
MySQL Shell import_table数据导入的实现
2021/08/07 MySQL
关于python pygame游戏进行声音添加的技巧
2021/10/24 Python