django URL路由基礎

URL是Web服務的入口,用戶通過瀏覽器發送過來的任何請求,都是發送到一個指定的URL地址,然后被響應。

在Django項目中編寫路由,就是向外暴露我們接收哪些URL的請求,除此之外的任何URL都不被處理,也沒有返回。通俗地理解,不恰當的形容,URL路由是你的Web服務對外暴露的API。

Django奉行DRY主義,提倡使用簡潔、優雅的URL,沒有.php.cgi這種后綴,更不會單獨使用0、2097、1-1-1928、00這樣無意義的東西,讓你隨心所欲設計你的URL,不受框架束縛。

一、概述

URL路由在Django項目中的體現就是urls.py文件,這個文件可以有很多個,但絕對不會在同一目錄下。實際上Django提倡項目有個根urls.py,各app下分別有自己的一個urls.py,既集中又分治,是一種解耦的模式。

隨便新建一個Django項目,默認會自動為我們創建一個/project_name/urls.py文件,并且自動包含下面的內容,這就是項目的根URL:

"""mysite URL ConfigurationThe `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
 1. Add an import: from my_app import views  2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views  1. Add an import: from other_app.views import Home  2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf  1. Import the include() function: from django.conf.urls import url, include  2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), ] 

前面一堆幫助性的文字,我們不用管,關鍵是默認導入了url和admin,然后有一條指向admin后臺的url路徑。

我們自己要編寫的url路由,基本也是這個套路。

二、Django如何處理請求

當用戶請求一個頁面時,Django根據下面的邏輯執行操作:

  1. 決定要使用的根URLconf模塊。通常,這是ROOT_URLCONF設置的值,但是如果傳入的HttpRequest對象具有urlconf屬性(由中間件設置),則其值將被用于代替ROOT_URLCONF設置。通俗的講,就是你可以自定義項目入口url是哪個文件!
  2. 加載該模塊并尋找可用的urlpatterns。?它是django.conf.urls.url()實例的一個列表。
  3. 依次匹配每個URL模式,在與請求的URL相匹配的第一個模式停下來。也就是說,url匹配是從上往下的短路操作,所以url在列表中的位置非常關鍵。
  4. 導入并調用匹配行中給定的視圖,該視圖是一個簡單的Python函數(被稱為視圖函數),或基于類的視圖。 視圖將獲得如下參數:
    1. 一個HttpRequest 實例。
    2. 如果匹配的正則表達式返回了沒有命名的組,那么正則表達式匹配的內容將作為位置參數提供給視圖。
    3. 關鍵字參數由正則表達式匹配的命名組組成,但是可以被django.conf.urls.url()的可選參數kwargs覆蓋。
  5. 如果沒有匹配到正則表達式,或者過程中拋出異常,將調用一個適當的錯誤處理視圖。

三、簡單示例

下面是一個簡單的 URLconf:

from django.conf.urls import urlfrom . import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), url(r'^articles/([0-9]{4})/$', views.year_archive), url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail), ] 

我們要編寫的就是上面urlpatterns列表中的一條條url,每條url,都是urlpatterns列表的一個元素。先后順序有重要關系,不能隨意擺放。最后一條的末尾建議添加一個逗號。

urlpatterns中的每條正則表達式在第一次訪問時被自動編譯,因此其匹配速度是非常快的。

注意:

  • 若要從URL中捕獲一個值,只需要在它周圍放置一對圓括號。
  • 不需要添加前導的反斜杠,因為每個URL都有。 例如,應該是^articles而不是^/articles
  • 每個正則表達式前面的'r'是可選的但是建議加上。它告訴Python這個字符串是“原始的” —— 字符串中任何字符都不應該轉義。

根據上面的urlconf,下面是一些請求的例子,以及它們將匹配到的url:

  • /articles/2005/03/將匹配列表中的第三個模式。Django將調用函數views.month_archive(request, '2005', '03')
  • /articles/2005/3/不匹配任何URL模式,因為列表中的第三個模式要求月份是兩個數字。
  • /articles/2003/將匹配列表中的第一個模式不是第二個,因為模式按順序從上往下匹配,第一個會首先被匹配。Django會調用函數views.special_case_2003(request)
  • /articles/2003不匹配任何一個模式,因為每個模式都要求URL以一個斜杠結尾。
  • /articles/2003/03/03/將匹配最后一個模式。Django將調用函數views.article_detail(request, '2003', '03', '03')

四、命名組

很多時候,我們需要獲取URL中的一些片段,作為參數,傳遞給處理請求的視圖。

上面的示例使用簡單的、沒有命名的正則表達式組(通過圓括號)來捕獲URL中的值并以位置參數的形式傳遞給視圖。

可以使用命名的正則表達式組來捕獲URL中的值并以關鍵字參數傳遞給視圖。

在Python的正則表達式中,命名組的語法是(?P<name>pattern),其中name是組的名稱,pattern是要匹配的模式。

下面是以上URLconf使用命名組的重寫:

from django.conf.urls import urlfrom . import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive), url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive), url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail), ] 

這個實現與前面的示例完全相同,只有一個細微的差別:捕獲的值作為關鍵字參數而不是位置參數傳遞給視圖函數。 像這樣:

  • /articles/2005/03/請求將調用views.month_archive(request, year='2005', month='03')函數,而不是views.month_archive(request, '2005', '03')
  • /articles/2003/03/03/請求將調用函數views.article_detail(request, year='2003', month='03', day='03')

在實際應用中,這讓你的URLconf更加明晰且不容易產生參數順序問題的錯誤。當然,這不是強制性的,也犧牲了一些簡潔性。

針對命名組和非命名組:

  • 如果有命名參數,則使用這些命名參數,忽略非命名參數。
  • 否則,它將以位置參數傳遞所有的非命名參數。

五、URLconf匹配請求URL中的哪些部分

請求的URL被看做是一個普通的Python字符串,URLconf在其上查找并匹配。進行匹配時將不包括GET或POST請求方式的參數以及域名。

例如,在https://www.example.com/myapp/的請求中,URLconf將查找myapp/

https://www.example.com/myapp/?page=3的請求中,URLconf也將查找myapp/

URLconf不檢查使用何種HTTP請求方法,所有請求方法POST、GET、HEAD等都將路由到同一個URL的同一個視圖。在視圖中,才根據具體請求方法的不同,進行不同的處理。

六、URL中捕獲的參數為字符串類型

每個捕獲的參數都作為一個普通的Python字符串傳遞給視圖,即便被捕獲的‘100’看起來像個整數,但實際上是個字符串‘100’。 例如,下面這行URLconf中:

url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),

傳遞給views.year_archive()的year參數將是一個字符串,不是整數,即使[0-9]{4}只匹配整數字符串。

七、指定視圖參數的默認值

有一個小技巧,我們可以指定視圖參數的默認值。 下面是一個URLconf和視圖的示例:

# URLconf
from django.conf.urls import urlfrom . import views urlpatterns = [ url(r'^blog/$', views.page), url(r'^blog/page(?P<num>[0-9]+)/$', views.page), ] # View (in blog/views.py) def page(request, num="1"): # Output the appropriate page of blog entries, according to num. ... 

在上面的例子中,兩個URL模式指向同一個視圖views.page。但是第一個模式不會從URL中捕獲任何值。 如果第一個模式匹配,page()函數將使用num參數的默認值"1"。 如果第二個模式匹配,page()將使用捕獲的num值。

八、自定義錯誤頁面

當Django找不到與請求匹配的URL時,或者當拋出一個異常時,將調用一個錯誤處理視圖。錯誤視圖包括400、403、404和500,分別表示請求錯誤、拒絕服務、頁面不存在和服務器錯誤。它們分別位于:

  • handler400 —— django.conf.urls.handler400。
  • handler403 —— django.conf.urls.handler403。
  • handler404 —— django.conf.urls.handler404。
  • handler500 —— django.conf.urls.handler500。

這些值可以在根URLconf中設置。在其它app中的二級URLconf中設置這些變量無效。

Django有內置的HTML模版,用于返回錯誤頁面給用戶,但是這些403,404頁面實在丑陋,通常我們都自定義錯誤頁面。

首先,在根URLconf中額外增加下面的條目:

# URLconf
from django.conf.urls import urlfrom . import views urlpatterns = [ url(r'^blog/$', views.page), url(r'^blog/page(?P<num>[0-9]+)/$', views.page), ] # 增加的條目 handler400 = views.bad_request handler403 = views.permission_denied handler404 = views.page_not_found handler500 = views.page_error 

然后在,views.py文件中增加四個處理視圖:

def page_not_found(request):return render(request, '404.html') def page_error(request): return render(request, '500.html') def permission_denied(request): return render(request, '403.html') def bad_request(request): return render(request, '400.html') 

再根據自己的需求,創建404.html、400.html等四個頁面文件,就可以了。

轉載于:https://www.cnblogs.com/navysummer/p/10200191.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/450241.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/450241.shtml
英文地址,請注明出處:http://en.pswp.cn/news/450241.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux在超級計算機領域一統天下

摘要&#xff1a;在世界超級計算機排行榜500強榜單中&#xff0c;基于Linux的超級計算機占據了462個席位&#xff0c;比率高達92%。基于Windows的超級計算機僅有2個席位&#xff0c;份額為0.4%。中國基于Windows的超級計算機Magic Cube排名94位&#xff0c;澳大利亞基于Windows…

Qtum量子鏈漏洞賞金計劃正式開啟

本次Qtum量子鏈賞金計劃為了更好的借助社區的力量參與到QTUM主網及周邊應用的開發建設中&#xff0c;讓QTUM持續地保持安全、高效的運行&#xff0c;同時能滿足更多用戶的需求。Bug分級與獎勵體系1、如果已經有類似的Issue或者Qtum團隊已經知道并在解決該問題的情況將不適用于該…

.SpelEvaluationException: EL1008E: Property or field ‘cache_department_list_Tree‘ cannot be found

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 報錯如題&#xff1a; .SpelEvaluationException: EL1008E: Property or field cache_department_list_Tree cannot be found on object…

修過的一個android framework原生系統代碼bug

“坑”描述&#xff1a; 在對我們自己研發的一款android終端進行camera拍照壓力測試時&#xff0c;發現當拍照張數達到幾萬張時&#xff0c;查看內存占用情況&#xff0c;發現內存泄露。 填“坑”&#xff1a; frameworks/base/core/jni/android/graphics/YuvToJpegEncoder.…

Koa項目搭建過程詳細記錄

2019獨角獸企業重金招聘Python工程師標準>>> Java中的Spring MVC加MyBatis基本上已成為Java Web的標配。Node JS上對應的有Koa、Express、Mongoose、Sequelize等。Koa一定程度上可以說是Express的升級版。許多Node JS項目已開始使用非關系型數據庫(MongoDB)。Sequel…

商業項目中代碼質量是否重要?

這是一篇比較老的 文章&#xff0c;但是文中的這些問題在現在仍然普遍存在。代碼質量的高低與商業產品的優劣是否有直接的影響&#xff1f;開發者Frank Sommers在文中給出了他的看法。文章內容如下。在大多數商業項目中&#xff0c;代碼質量并不被看重&#xff0c;因為大部分情…

Class is not a root resource. It, or one of its interfaces must be annotated with @Path:

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 報錯如題&#xff1a; Class is not a root resource. It, or one of its interfaces must be annotated with Path:XXXX 這是一個dub…

Equation漏洞混淆利用分析總結(下)

樣本三 如下所示在該樣本中&#xff0c;使用了Ole10Native的流&#xff0c;因此沒有equative head&#xff0c;默認讀取紅框中的4位長度。之后的metf head為01. 可以看到metf head的長度為01時&#xff0c;直接進入到if判斷中(該if中的函數實際是一個異常處理函數&#xff0c;但…

閑扯工程師的版本管理概念

如果你所在的公司還在通過qq給客戶發sdk升級包等&#xff0c;你可以考慮換一家公司了。

resource fork, Finder information, or similar detr

1.關閉當前項目和Xcode 2.打開終端或者iterm cd ~/Library/Developer/Xcode/DerivedData/ 3. xattr -rc . 4.重新打開項目 5.如果不行那你就再試試其他的辦法吧&#xff0c;我就是這樣弄好的 如果有需要裝系統的話可以看一下我自己封裝的系統&#xff0c;原裝系統無精簡&#x…

5 個常用的軟件質量指標

在軟件開發中&#xff0c;軟件質量是衡量軟件是否符合需求、標準的重要體現。除了 代碼質量外&#xff0c;影響軟件整體質量的因素還有很多。因此&#xff0c;要確保軟件的整體質量&#xff0c;就需要在各個環節嚴格控制。本文列出了衡量軟件質量的5個最常用的指標。1. SLOC&a…

介紹一個對陌生程序快速進行性能瓶頸分析的技巧

前言 工作多年&#xff0c;一直做的是curd系統。前幾年做的系統應用場景&#xff0c;大多對數據庫依賴比較重。例如報表統計&#xff0c;數據遷移&#xff0c;批量對賬等。所以這些系統出現性能瓶頸一般出在數據庫操作上面。 如果程序因為數據庫操作出現性能瓶頸是比較好辦的&a…

[WARNING] The POM for XXX-system:jar:1.9.0-SNAPSHOT is missing, no dependency information available

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 在 git-bash 中 想要啟動一個工程服務就是不成功&#xff0c;始終提示jar包找不到&#xff0c;本地代碼已提交。 這時可直接登陸git&am…

關于tcp網絡通訊的幾個場景的小測試

以下場景基于阻塞式IO 發送端向接收端快速的發送數據&#xff0c;接收端如果不接受或者很慢速的接受會發生什么情況。 發送端快速向接收端發送大量數據&#xff0c;然后立即退出&#xff0c;接收端會發生什么情況。

測試一體機ASM failgroup的相關問題處理

環境&#xff1a;3臺虛擬機 RHEL 7.3 Oracle RAC 11.2.0.4問題現象&#xff1a;RAC運行正常&#xff0c;ASM磁盤組Normal冗余&#xff0c;有failgroup整體故障&#xff0c;有failgroup配置錯誤。溫馨提示&#xff1a;本文并不是市場上任何一款商業的一體機產品&#xff0c;只是…

掌握窮變富的12條原則 迅速從普通人變成有錢人

“窮忙”和“富閑”是對立面&#xff0c;“窮”對“忙”&#xff0c;“富”對“閑”&#xff0c;很多“窮忙女”是在拿青春當賭注&#xff0c;希望自己今天的“美麗”明天就能在市場上有個不錯的“回報”&#xff1b;而多數“富閑女”則是在拿智慧當籌碼&#xff0c;既不可替代…

com.alibaba.dubbo.rpc.RpcException: Forbid consumer 192.168.184.1 access service com.foreveross.syst

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 報錯如下&#xff1a; com.alibaba.dubbo.rpc.RpcException: Forbid consumer 192.168.XXX.1 access service com.XXX.system.service.…

動手又動腦

1.編寫一個程序&#xff0c;指定一個文件夾&#xff0c;能自動計算出其總容量。 import java.io.File; import java.io.IOException; public class FileEdit { double size0.0; //計算文件或文件夾的大小&#xff0c;單位MB public double getSize(File file){ //判斷文件是否存…

windows下安裝和設置gradle

一、安裝前檢查 檢查jdk是否已經安裝 二、下載gradle 1. https://gradle.org/releases/ 2.設置gradle環境變量 3. 環境變量中增加名為GRADLE_HOME的變量名,值為Gralde的解壓路徑,例如D:\Gradle 在path的后追加%GRADLE_HOME%\bin; 4. 驗證 5.修改默認緩存目錄 修改Gradle默認緩存…

智能硬件的時代,嵌入式是否已經日薄西山

存吐吐槽&#xff0c;智能硬件現在很火熱&#xff0c;導致很多人以為嵌入式行業又迎來了春天&#xff0c;可是明白人都知道&#xff0c;智能硬件核心在智能&#xff0c;硬件是很次要的。目前的硬件產品&#xff0c;要有亮點&#xff0c;都和智能沾邊&#xff0c;已經不是那個可…