Django系列教程(7)——路由配置URLConf

目录

URLconf是如何工作的?

path和re_path方法

更多URL配置示例

URL的命名及reverse()方法

使用命名URL

硬编码URL - 不建议

URL指向基于类的视图(View)

通过URL传递额外的参数

小结


Django的项目文件夹和每个应用(app)目录下都有urls.py文件,它们构成了Django的路由配置系统(URLconf)。服务器收到用户请求后,会根据用户请求的url地址和urls.py里配置的url-视图映射关系,去调用执行相应的视图函数或视图类,最后由视图返回给客户端数据。

一个优美的URL不仅层次分明、逻辑清晰,而且便于搜索引擎收录。一个糟糕的URL不仅可读性差,而且易造成程序冲突。本章小编我将给大家详细介绍下如何在Django项目开发中进行路由配置。

URLconf是如何工作的?

假如我们有一个blog的博客应用,你需要编写两个视图函数,一个用于展示文章列表,一个用于展示文章详情,你的urls.pyviews.py正常情况下应如下所示:

# blog/urls.py
from django.urls import path
from . import viewsurlpatterns = [path('blog/', views.index),path('blog/articles/<int:id>/', views.article_detail),
]# blog/views.py
def index(request):# 展示所有文章def article_detail(request, id):# 展示某篇具体文章

那么上面这段代码是如何工作的呢?

  • 当用户在浏览器输入/blog/时,URL收到请求后会调用视图views.py里的index方法,展示所有文章
  • 当用户在浏览器输入/blog/article/<int:id>/时,URL不仅调用了views.py里的article_detail方法,而且还把参数文章id通过<>括号的形式传递给了视图。int这里代表只传递整数,传递的参数名字是id。

在上述代码中,我们通过urlpatterns列表的url-视图映射关系列表起了决定性作用,起到了任务调度的作用。

注意:注意当你配置URL时,别忘了把你的应用(blog)的urls加入到项目的URL配置里(mysite/urls.py), 如下图所示:

from django.urls import include, pathurlpatterns = [path('', include('blog.urls')),...
]

path和re_path方法

写个URL很简单,但如何通过URL把参数传递给给视图view是个技术活。Django提供了两种设计URL的方法: pathre_path,它们均支持向视图函数或类传递参数。path是正常参数传递,re_path是采用正则表达式regex匹配。pathre_path传递参数方式如下:

  • path方法:采用双尖括号<变量类型:变量名><变量名>传递,例如<int:id><slug:slug><username>

  • re_path方法: 采用命名组(?P<变量名>表达式)的方式传递参数。

下例中,我们分别以pathre_path 定以了两个urls,它们是等效的,把文章的id(整数类型)传递给了视图。re_path里引号前面的小写r表示引号里为正则表达式, ^代表开头,$代表以结尾,\d+代表正整数。

# blog/urls.py
from django.urls import path, re_path
from . import viewsurlpatterns = [path('blog/articles/<int:id>/', views.article_detail, name = 'article_detail'),re_path(r'^blog/articles/(?P<id>\d+)/$', views.article_detail, name='article_detail'),
]# blog/views.py
def article_detail(request, id):# 展示某篇文章

在使用pathre_path方法设计urls需注意:

  • url中的参数名要用尖括号,而不是圆括号;
  • 匹配模式的最开头不需要添加斜杠/,但建议以斜杠结尾;
  • 使用re_path时不一定总是以$结尾,有时不能加。比如下例中把blog.urls通过re_path加入到项目urls中时就不能以$结尾,因为这里的blog/并不是完整的url,只是一个开头而已。
from django.urls import include, re_pathurlpatterns = [re_path(r'^blog/', include('blog.urls')),...
]

更多URL配置示例

path支持匹配的数据类型只有str,intsluguuid四种。一般来说re_path更强大,但写起来更复杂一些,我们来看看更多案例。

# 示例一,PATH
from django.urls import path
from . import viewsurlpatterns = [path('articles/2003/', views.special_case_2003),path('articles/<int:year>/', views.year_archive),path('articles/<int:year>/<int:month>/', views.month_archive),path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
]# 示例二:RE_PATH,与上例等同
from django.urls import path, re_path
from . import viewsurlpatterns = [path('articles/2003/', views.special_case_2003),re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$', views.article_detail),
]

同样以博客为例,如果你希望设计不同的urls分别对应负责增删改查操作的视图函数或类,你可以按如下设计:

# blog/urls.py
from django.urls import path, re_path
from . import views# app_name = 'blog' # 命名空间,后面会用到。
urlpatterns = [path('blog/articles/', views.article_list, name = 'article_list'),path('blog/articles/create/', views.article_create, name = 'article_create'),path('blog/articles/<int:id>/', views.article_detail, name = 'article_detail'),path('blog/articles/<int:id>/update/', views.article_update, name = 'article_update'),path('blog/articles/<int:id>/delete/', views.article_update, name = 'article_delete'),
]

URL的命名及reverse()方法

你注意到没?在上述博客示例中,我们中还给每个URL取了一个名字,比如 article_listarticle_create。这个名字大有用处,相当于给每个URL取了个全局变量的名字。它可以让你能够在Django的任意处,尤其是模板内显式地引用它。假设你需要在模板中通过链接指向一篇具体文章,下面那种方式更好?

使用命名URL

{% for article in articles %}<a href="{% url 'article_detail' article.id %}">{{ article.title }}</a>
{% endfor %}

url是个模板标签,其作用是对命名的url进行方向解析,动态生成链接。

注意:命名的url里有几个参数,使用url模板标签反向生成动态链接时,就需要向它传递几个参数。比如我们的命名urlarticle_detail里有整数型id这个参数,我们在模板中还需要传递article.id

硬编码URL - 不建议

{% for article in articles %}<a href="blog/articles/{{ article.id }}">{{ article.title }}</a>
{% endfor %}

如果你还没意识到方法1的好处,那么想想吧,假设老板让你把全部模板链接由blog/articles/id改为blog/article/id, 那种方法更快?更改所有html文件里的链接,还是只改URL配置里的一个字母?

那么问题来了。假设不同的app(比如news和blog)里都有article_detail这个命名URL, 我们怎么避免解析冲突呢? 这时我们只需要在blog/urls.py加上app_name='blog'这个命名空间即可,然后在模板中以blog:article_detail使用即可。

{% for article in articles %}<a href="{% url 'blog:article_detail' article.id %}">{{ article.title }}</a>
{% endfor %}

可惜的是命名的URL一般只在模板里使用,不能直接在视图里使用。如果我们有了命名的URL,我们如何把它转化成常规的URL在视图里使用呢?

Django提供的reverse()方法很容易实现这点。它在视图中可以对命名urls进行反向解析,生成动态链接。

from django.urls import reverse# output blog/articles/id
reverse('blog:article_detail', args=[id]) 

URL指向基于类的视图(View)

目前pathre_path都只能指向视图view里的一个函数或方法,而不能直接指向一个基于类的视图(Class based view)。Django提供了一个额外as_view()方法,可以将一个类伪装成方法。这点在当你使用Django自带的类视图或自定义的类视图时非常重要。

具体使用方式如下:

# blog/urls.py
from django.urls import path, re_path
from . import viewsurlpatterns = [# path('blog/articles/', views.article_list, name = 'article_list'),path('blog/articles/', views.ArticleList.as_view(), name='article_list'),
]# View (in blog/views.py)
from django.views.generic import ListView
from .views import Articleclass ArticleList(ListView):queryset = Article.objects.filter(date__lte=timezone.now()).order_by('date')[:5]context_object_name = 'article_list‘template_name = 'blog/article_list.html'

如果你对基于类的视图还比较困惑,没有关系,我们后面会做详细介绍。

通过URL传递额外的参数

在你配置URL时,你还可以通过字典的形式传递额外的参数给视图, 而不用把这个参数写在链接里。如下面案例所示:

# blog/urls.py
from django.urls import path, re_path
from . import viewsurlpatterns = [path('', views.ArticleList.as_view(), name='article_list', {'blog_id': 3}),
]

小结

本章我们讲解了如何使用pathre_path方法进行url配置,并详细介绍了什么命名的urls以及如何使用url模板标签和 reverse方法对命名urls进行反向解析。下篇文章中我们将正式介绍视图的编写,欢迎阅读。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/72096.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

transformer bert 多头自注意力

输入的&#xff08;a1,a2,a3,a4&#xff09;是最终嵌入&#xff0c;是一个(512,768)的矩阵&#xff1b;而a1是一个token&#xff0c;尺寸是768 a1通过wq权重矩阵&#xff0c;经过全连接变换得到查询向量q1&#xff1b;a2通过Wk权重矩阵得到键向量k2&#xff1b;q和k点乘就是值…

Spring Boot + MyBatis-Plus 项目目录结构

以下是一个标准的 Spring Boot MyBatis-Plus 项目目录结构及文件命名规范&#xff0c;包含每个目录和文件的作用说明&#xff0c;适用于中大型项目开发&#xff1a; 项目根目录结构 src/ ├── main/ │ ├── java/ # Java 源代码 │ │ └── com/…

Webpack优化前端性能

Webpack优化前端性能☆☆ 涵盖了代码分割、懒加载、压缩、缓存优化、Tree Shaking、图片优化、CDN使用等多个方面。 Webpack优化前端性能详解(2025综合实践版) Webpack作为现代前端工程化的核心工具,其优化能力直接影响项目的首屏速度、交互流畅度和用户体验。以下从代码维…

ardunio R4 WiFi连接实战

ardunio WiFi连接模板 ardunio R4 WiFi 开发板有着不错的性能和板载内存&#xff0c;本机自带 WiFi 连接模块&#xff0c;可以完成简单的网络服务。对于这个小东西我情有独钟&#xff0c;也总希望能够用它来做些什么&#xff0c;所以先从 WiFi 连接开始学起&#xff0c;未来考…

C++11 编译使用 aws-cpp-sdk

一、对sdk的编译前准备 1、软件需求 此文档针对于在Linux系统上使用源码进行编译开发操作系统使用原生的contos7Linux。机器配置建议 内存8G以上,CPU 4个 以上GCC 4.9.0 及以上版本Cmake 3.12以上 3.21以下apt install libcurl-devel openssl-devel libuuid-devel pulseaudio-…

得物 Android Crash 治理实践

一、前言 通过修复历史遗留的Crash漏报问题&#xff08;包括端侧SDK采集的兼容性优化及Crash平台的数据消费机制完善&#xff09;&#xff0c;得物Android端的Crash监控体系得到显著增强&#xff0c;使得历史Crash数据的完整捕获能力得到系统性改善&#xff0c;相应Crash指标也…

SpringBoot3+Lombok如何配置logback输出日志到文件

Background/Requirement SpringBoot3Lombok如何配置logback输出日志到文件&#xff0c;因为我需要对这些日志进行输出&#xff0c;控制台输出和文件输出&#xff0c;文件输出是为了更好的作为AuditLog且支持滚动式备份&#xff0c;每天一个文件。 Technical Solution 1.确保你…

主流向量数据库对比

在 AI 的 RAG&#xff08;检索增强生成&#xff09;研发领域&#xff0c;向量数据库是存储和查询向量嵌入的核心工具&#xff0c;用于支持高效的语义搜索和信息检索。向量嵌入是文本或其他非结构化数据的数值表示&#xff0c;RAG 系统通过这些嵌入从知识库中检索相关信息&#…

搞定python之四----函数、lambda和模块

本文是《搞定python》系列专栏的第四篇&#xff0c;通过代码演示列python自定义函数、lambda和模块的用法。本文学习完成后&#xff0c;python的基础知识就完了。后面会学习面向对象的内容。 1、自定义函数 # 测试python自定义函数# 有参数&#xff0c;没有返回值 def say_he…

[操作系统] 学校课程关于“静态优先级抢占式调度“作业

今天我们来分享两道题目哈, 学校弄得题目. T1: 静态优先级, 抢占式(1为高优先级) 图解: 以下是静态优先级抢占式调度的解题过程和结果&#xff1a; 解题思路&#xff1a; 优先级规则&#xff1a; 数值越小优先级越高。新进程到达时&#xff0c;若其优先级高于当前运行进程&…

洛谷P1320 压缩技术(续集版)

P1320 压缩技术&#xff08;续集版&#xff09; 题目描述 设某汉字由 N N N \times N NN 的 0 \texttt 0 0 和 1 \texttt 1 1 的点阵图案组成。 我们依照以下规则生成压缩码。连续一组数值&#xff1a;从汉字点阵图案的第一行第一个符号开始计算&#xff0c;按书写顺序从…

使用DeepSeek完成一个简单嵌入式开发

开启DeepSeek对话 请帮我使用Altium Designer设计原理图、PCB&#xff0c;使用keil完成代码编写&#xff1b;要求&#xff1a;使用stm32F103RCT6为主控芯片&#xff0c;控制3个流水灯的原理图 这里需要注意&#xff0c;每次DeepSeek的回答都不太一样。 DeepSeek回答 以下是使…

volatile、synchronized和Lock

名词解释&#xff1a; 指令重排是计算机为了优化执行效率&#xff0c;在不改变单线程程序结果的前提下&#xff0c;对代码的执行顺序进行重新排列的操作。它可能发生在编译阶段&#xff08;编译器优化&#xff09;或CPU运行阶段&#xff08;处理器优化&#xff09;。 举个栗子…

嵌入式八股C语言---面向对象篇

面向对象与面向过程 面向过程 就是把整个业务逻辑分成多个步骤,每步或每一个功能都可以使用一个函数来实现面向对象 对象是类的实例化,此时一个类就内部有属性和相应的方法 封装 在C语言里实现封装就是实现一个结构体,里面包括的成员变量和函数指针,然后在构造函数中,为结构体…

Distilling the Knowledge in a Neural Network知识蒸馏

一.知识蒸馏的定义 1. 量化VS蒸馏 量化&#xff1a;减小精度 例如参数float32—>float16蒸馏&#xff1a;Student model模仿Teacher model,在保持较高性能的同时&#xff0c;减少模型大小和计算复杂度的技术。 二.知识蒸馏步骤 1.教师模型训练: 训练一个大型且复杂的神…

静态程序分析

参考&#xff1a;https://github.com/RangerNJU/Static-Program-Analysis-Book/blob/master/SUMMARY.md 课件&#xff1a;https://pascal-group.bitbucket.io/teaching.html 视频&#xff1a;南京大学《软件分析》课程01&#xff08;Introduction&#xff09;_哔哩哔哩_bilib…

Flutter_学习记录_device_info_plus 插件获取设备信息

引入三方库device_info_plus导入头文件 import package:device_info_plus/device_info_plus.dart;获取设备信息的主要代码 DeviceInfoPlugin deviceInfoPlugin DeviceInfoPlugin(); BaseDeviceInfo deviceInfo await deviceInfoPlugin.deviceInfo;完整案例 import package…

日有所得-google 浏览器离线安装

一、目标&#xff1a; 基于UOS系统进行浏览器插件开发&#xff0c;目标展现形式为侧栏 二、背景&#xff1a; UOS操作系统需支持1032及以上版本 浏览器插件基于google浏览器&#xff0c;自带360等浏览器能兼容基于google浏览器开发的插件 JS库借用Vue库以提高效率 三、问…

高效自动化测试:打造Python+Requests+Pytest+Allure+YAML的接口测试框架

一、背景 在快节奏的开发周期中&#xff0c;如何确保接口质量&#xff1f;自动化测试是关键。通过构建标准化、可复用的测试框架&#xff0c;能显著提升测试效率与准确性&#xff0c;为项目质量保驾护航[1][7]。 二、目标 ✅ 核心目标&#xff1a; ● 实现快速、高效的接口测试…

谈谈List,Set,Map的区别

List、Set 和 Map 是 Java 集合框架&#xff08;Java Collections Framework&#xff09;中的三种主要接口&#xff0c;它们各自有不同的特点和用途。以下是它们的区别和使用场景的详细解释&#xff1a; 1. List&#xff08;列表&#xff09; 1.1 特点 有序集合&#xff1a;Li…