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,int,?slug,?uuid四種。一般來說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.pswp.cn/web/72096.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/72096.shtml
英文地址,請注明出處:http://en.pswp.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…