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

news2025/3/14 5:41:03

目录

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 views
 
urlpatterns = [
    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, path

urlpatterns = [
    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 views
 
urlpatterns = [
    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_path

urlpatterns = [
    re_path(r'^blog/', include('blog.urls')),
    ...
]

更多URL配置示例

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

# 示例一,PATH
from django.urls import path
from . import views

urlpatterns = [
    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 views

urlpatterns = [
    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 views
 
urlpatterns = [
    # 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 Article
 
class 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 views
 
urlpatterns = [
    path('', views.ArticleList.as_view(), name='article_list', {'blog_id': 3}),
]

小结

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

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

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

相关文章

2024年第十五届蓝桥杯软件C/C++大学A组——五子棋对弈

蓝桥杯原题&#xff1a; 题目描述&#xff1a; “在五子棋的对弈中&#xff0c;友谊的小船说翻就翻&#xff1f; ” 不&#xff01;对小蓝和小桥来说&#xff0c;五子棋不仅是棋盘上的较量&#xff0c;更是心与心之间的沟通。这两位挚友秉承着 “ 友谊第一&#xff0c;比赛第二…

复试难度解析,西电先进材料与纳米科技学院学院考研录取情况

01、先进材料与纳米科技学院各个方向 02、24先进材料与纳米科技学院近三年复试分数线对比 PS&#xff1a;材料院24年院线学硕方向降低10分&#xff0c;专硕上涨15分&#xff1b;材料院在分数线相对于其他211、985院校对比来看&#xff0c;依然分数偏低&#xff0c;推荐大家关注…

Deepseek Chatgpt Kimi 推荐的深度学习书单

朋友让推荐一些深度学习的书&#xff0c;让 Deepseek、Chatgpt、Kimi 分别生成了一份书单并做了对比&#xff0c;记录一下以备以后用到。 Chatgpt 推荐的深度学习书 1. chatgpt 推荐的书目截图 1.2 Chatgpt 推荐的深度学习书目文字版 如果你想学习 Deep Learning&#xff0…

高频面试题(含笔试高频算法整理)基本总结回顾25

干货分享&#xff0c;感谢您的阅读&#xff01; &#xff08;暂存篇---后续会删除&#xff0c;完整版高频面试题基本总结回顾&#xff08;含笔试高频算法整理&#xff09;&#xff09; 备注&#xff1a;引用请标注出处&#xff0c;同时存在的问题请在相关博客留言&#xff0c…

mac安装mysql之后报错zsh: command not found: mysql !

在Mac上安装MySQL后&#xff0c;如果终端中找不到mysql命令&#xff0c;通常是 因为MySQL的命令行工具&#xff08;如mysql客户端&#xff09;没有被正确地添加到你的环境变量中。 检查 MySQL 是否已安装 ps -ef|grep mysql查看到路径在 /usr/local/mysql/bin 查看 .bash_pro…

蓝桥杯备考:set容器用法(lower_bound)---营业额统计

如图所示&#xff0c;这道题的暴力解法就是枚举每天的营业额&#xff0c;让该营业额和前面的天的营业额依次相减取最小值这样的话我们的时间复杂度就是N平方&#xff0c;我们是很有可能超时的 所以我们选择用set容器的二分查找功能 我们每次遍历到一个数的时候&#xff0c;前…

VSCode集成C语言开发环境

下载MinGW https://sourceforge.net/projects/mingw/ 点击download按钮下载exe文件到本地 点击exe文件安装 选择基础包和c编译版 vscode安装部分跳过 安装code runner和c/c插件 **(1) 创建 C 文件** 新建一个测试文件&#xff08;例如 hello.c&#xff09;&#xf…

Python----数据可视化(pyecharts二:绘图一:条形图,直方图,折线图,散点图,箱图,饼图,热力图)

1、条形图 from pyecharts.charts import Bar from pyecharts.faker import Faker from pyecharts import options as opts # 绘制柱状图 bar (Bar() # 创建柱状图.add_yaxis("商家A", Faker.values(),colorFaker.rand_color()) # 添加数据.add_yaxis("商家B&…

Training-free Neural Architecture Search for RNNs and Transformers(预览版本)

摘要 神经架构搜索 (NAS) 允许自动创建新的有效神经网络架构&#xff0c;为手动设计复杂架构的繁琐过程提供了替代方案。然而&#xff0c;传统的 NAS 算法速度慢&#xff0c;需要大量的计算能力。最近的研究调查了图像分类架构的无训练 NAS 指标&#xff0c;大大加快了搜索算…

计算机考研C语言

C语言程序设计从入门到精通【2025完整版】考研复试 嵌入式 计算机二级 软考 专升本也适用_哔哩哔哩_bilibili 1、第一个C程序 helloC #include <stdio.h>int main(){printf("hehe");return 0;}每个C语言程序不管有多少行代码&#xff0c;都是从main函数开始执…

【MySQL】(4) 表的操作

一、创建表 语法&#xff1a; 示例&#xff1a; 生成的数据目录下的文件&#xff1a; 二、查看表结构 三、修改表 语法&#xff1a; 另一种改表名语法&#xff1a;rename table old_name1 to new_name1, old_name2 to new_name2; 示例&#xff1a; 四、删除表 语法&#xf…

Qt 中实现自定义控件子类化

一、子类化关键步骤 ‌1、选择基类‌ 根据需求选择合适的 Qt 原生控件作为基类&#xff08;如 QWidget、QPushButton、QSpinBox 等&#xff09;&#xff0c;通过继承实现功能扩展‌。 ‌2、重写关键方法‌ ‌绘制逻辑‌&#xff1a;重写 paintEvent() 方法&#xff0c;使用 Q…

6. MySQL 索引的数据结构(详细说明)

6. MySQL 索引的数据结构(详细说明) 文章目录 6. MySQL 索引的数据结构(详细说明)1. 为什么使用索引2. 索引及其优缺点2.1 索引概述 3. InnoDB中索引的推演3.1 索引之前的查找3.2 设计索引3.3 常见索引概念1. 聚簇索引2. 二级索引&#xff08;辅助索引、非聚簇索引&#xff09;…

pytorch 50 大模型导出的onnx模型优化尝试

本博文基于Native-LLM-for-Android项目代码实现,具体做了以下操作: 1、尝试并实现将模型结构与权重零散的onnx模型进行合并,通过该操作实现了模型加载速度提升,大约提升了3倍 2、突破了onnxconverter_common 无法将llm模型导出为fp16的操作,基于该操作后将10g的权重降低到…

LeetCode1871 跳跃游戏VII

LeetCode 跳跃游戏 IV&#xff1a;二进制字符串的跳跃问题 题目描述 给定一个下标从 0 开始的二进制字符串 s 和两个整数 minJump 和 maxJump。初始时&#xff0c;你位于下标 0 处&#xff08;保证该位置为 0&#xff09;。你需要判断是否能到达字符串的最后一个位置&#xf…

RabbitMQ 从入门到精通

1 MQ架构设计原理 1.1 什么是消息中间件 消息中间件基于队列模型实现异步/同步传输数据 作用&#xff1a;可以实现支撑高并发、异步解耦、流量削峰、降低耦合度。 1.2 传统的http请求存在那些缺点 1.Http请求基于请求与响应的模型&#xff0c;在高并发的情况下&#xff0c…

考研复试c语言常见问答题汇总2

11. 关键字和一般标识符有什么不同&#xff1f; C语言中关键字与一般标识符区别&#xff1a; 定义&#xff1a;关键字是C语言预定义的特殊单词&#xff08;如int、for&#xff09;&#xff0c;有固定含义&#xff1b;标识符是自定义的名称&#xff08;如变量名、函数名&#xf…

Qt表格美化笔记

介绍 表格是一种常见的数据管理界面形式&#xff0c;在大批量的数据交互情形下使用的比较多 表格 可以通过样式表设置线条以及边框的颜色 QTableWidget { gridline-color : rgb(55, 60, 62); border: 1px solid rgb(62,112,181);}表头 如果表头和第一行的分割线显示&#…

『PostgreSQL』PGSQL备份与还原实操指南

&#x1f4e3;读完这篇文章里你能收获到 了解逻辑备份与物理备份的区别及适用场景&#x1f50d;。掌握全库、指定库、指定表备份还原的命令及参数&#x1f4dd;。学会如何根据业务需求选择合适的备份策略&#x1f4ca;。熟悉常见备份还原问题的排查与解决方法&#x1f527;。 …

Redis 主从复制详解:实现高可用与数据备份

目录 引言 1. 什么是 Redis 主从复制&#xff1f; 1.1 定义 1.2 核心概念 2. Redis 主从复制的工作原理 2.1 复制流程 2.2 复制流程图 3. Redis 主从复制的配置方法 3.1 通过配置文件配置 主节点配置 从节点配置 3.2 通过命令行配置 设置从节点 取消从节点 4. Re…