day64 url用法以及django的路由系统
?
此篇博客是以備后查的,用到的時候記得過來查找即可!
?
路由系統:就是我們的django項目創建的時候自帶的那個urls.py
它本身里面是映射的對應關系,一個大的列表里面,一個個元祖,元祖里面是url或者網址,對應一個函數,視圖函數(處理業務邏輯)
url配置(URLconf)就像django所支撐的網站目錄,它的本質是URL與要為該URL調用的視圖函數之間的映射表
就像我們在創建django的時候系統自動生成的那個url.py文件一樣,里面的url列表里面我們就是寫入了一個個的元祖,然后每一個元祖里面是url地址和與之對應的那個函數名,我們使用這個url的時候就是要執行那個函數,
urlconf配置
基本格式如下:
from django.conf.urls import urlurlpatterns = [url(正則表達式, views視圖函數,參數,別名), ]django2.0版本中的路由系統已經替換成了下面的寫法: from django.urls import pathurlpatterns = [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), ]
在web中的參數傳遞有兩種方式,一種是寫到類或者是函數的參數中,同時在URL中也顯示出來,以‘?xxx=xxx’的方式顯示出來,還有一種就是隱性傳參的方式,用request.POST/GET.get()的方式獲取參數。
跟前端的交互方式也不一樣
參數說明:
正則表達式,一個正則表達式字符串,
正則表達式的url匹配模式,我們的正則是有分組的,如果是單純的分組的話,它的分好的每一個組都是位置參數,我們的位置參數是使用
arg去接收的,
我們的分組是會有分組命名的,那么命好的名字就是關鍵字參數,我們使用**kwargs來接收2我們的關鍵字傳參
views視圖函數,一個可調用對象,通常為一個視圖函數或者一個指定視圖函數路徑的字符串
參數:可選的要傳遞給視圖函數的默認參數(字典形式)
別名:一個可選的name參數
正則表達式詳解
基本配置:
我們之前寫的那些url映射關系里面,都是寫死的,就是一個url我們對應一個視圖函數,這樣使用起來很不方便,
我們需要進行優化,把他們的規律掌握了之后,在一定范圍內都使用一個視圖函數,這樣就可以極大地提高我們的工作效率了
所以我們需要使用正則來找到他們的規律
from django.conf.urls import url
from . 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),
]
?這里我們使用正則匹配的時候就是按照我們之前所學的那些正則的規則去一一匹配,
這里是沒有異議的
注意事項:
分組命名匹配:
我們的上面的正則是無法取到該頁面的,需要進行分組來執行才可以得到我們需要的結果,傳參數的時候順序要一一對應, 我們使用的正則是有分組的,每個分組之間用()來分割,
上面的示例使用簡單的正則表達式分組匹配(通過圓括號)來捕獲URL中的值并以位置參數形式傳遞給視圖。
在更高級的用法中,可以使用分組命名匹配的正則表達式組來捕獲URL中的值并以關鍵字參數形式傳遞給視圖。
(?P<name>pattern)? ?====>這里面的(?)都是固定格式,P也是固定的,它就是分組命名的關鍵字,我們的P后面的<>存放我們自定義的分組的名字,
把上面的urlconf使用命名組重寫:
from django.conf.urls import url
from . 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),
]
?而我們的分組命名匹配寫到了我們的url里面,那樣我們的url因為分組的原因,僅僅是因為分組加上了括號,意義就大不一樣了,它系統識別到了分組就會把分組的每一個組生成一個操作,這個操作就是每一個分組都是一個參數,而且是直接傳遞過去的參數,一旦我們刷新頁面的時候那個生成的分組的參數就自動傳遞給了后端,而后端沒有接收到它的話就會報錯,提示你有關鍵字參數需要傳遞,而你沒有接收它,這就是問題所在,所以我們需要在我們的views函數里面加上參數去接收我們在分組里面的傳值操作,
我們的分組里面如果有命名的話,我們命的名字要和我們在views函數里面的接收的參數名保持一致或者我們直接就用到我們的**kwargs,來接收所有傳過來的關鍵字參數,
?
我們的url配置參數里面的name屬性里面的值跟我們在HTML文件里面,form表單里面的action對應的值是有關系的,這里就牽扯到了反向解析的問題,我們為了使用動態的效果,需要使用到反向解析的概念,這里就牽扯到一個命名的問題,我們的命名是不可以出現重復的,但是我們這里可以解決命名重復的問題,那就涉及到命名空間的使用了,我們可以把這些名字都存放于一個空間里面,在這個空間里面我們不使用重復的名字就好,但是超過這個空間的范圍我們就可以使用到重復的name值了,
所以我們使用命名空間的話,我們需要在我們的HTML文件里面的action里面加上名稱空間的名字,這里使用:進行拼接,我們上面提到的正則分組里面涉及到參數傳遞的問題,在views函數里面需要有參數傳遞,在對應的HTML文件里面也需要有參數設定,參數使用我們在分組正則里面命名的那個參數,也是鍵對值的方式,使用=連接,
還有就是我們的url網址輸入的時候,我們需要把我們自己的App里面的那個url地址和我們的django項目里面的url地址拼接到一起,輸入到網頁的地址欄里面,拼接的時候使用/分割,這樣就可得到我們的預期結果了.
?1,使用url的時候,注意我們的url地址拼接,在網址欄輸入時的地址拼接
2.注意正則匹配的時候我們的分組,以及分組命名,要跟我們的views視圖函數以及我們的HTML文件里面的 action對應的值,以及里面的參數配置
urlconf匹配的位置
urlconf在請求的url上查找,將它作為一個普通的python字符串來使用,不包括get和post以及參數和域名
例如一個網址:http://www.example.com/myapp/ 這里面我們的urlconf只查找myapp/
在http://www.example.com/myapp/?page=3 請求中,URLconf 仍將查找myapp/。 后面的?就是分隔符,我們的請求網址截止到?后面就是參數了,而.com前則是域名,參數和域名我們都是不包括在內的
?
捕獲的參數永遠都是字符串,
每個在urlconf中捕獲的參數都作為一個普通的python字符串傳遞個視圖,無論正則表達式用什么樣的匹配方式得到結果,它的本質是不會變的,都是字符串,
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),傳遞到視圖函數views.year_archive()?中的year?參數永遠是一個字符串類型。
?
我們的url路由配置里面,如果遇到了CBV,類視圖函數:
url(r'^login/$',views.LoginView.as_view),? ?# 這里我們解釋一下,如果是類視圖函數的話,我們的正則匹配的地址后面,要寫上我們的類名+View.as_view 這是固定格式,我們的類視圖函數需要繼承View,必須首字母大寫,固定格式.
視圖函數中指定默認值:
# urls.py中
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^blog/$', views.page),
url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
]
# views.py中,可以為num指定默認值
def page(request, num="1"):
pass
?
?
include其他的urlconfs:
#At any point, your urlpatterns can “include” other URLconf modules. This
#essentially “roots” a set of URLs below other ones.
#For example, here’s an excerpt of the URLconf for the Django website itself.
#It includes a number of other URLconfs:
from django.conf.urls import include, url
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^blog/', include('blog.urls')), # 可以包含其他的URLconfs文件
]
?這里的應用場景是,我們一個項目做成不是基于一個人,而是一整個團隊的努力我們的團隊里面是有分工合作的,既然牽扯到團隊的話,我們需要分工合作,每個人負責不同的部分,一個人負責的片區我們可以把它放到一個類似于口袋的地方,我們一整個項目完成后,再后期需要有更新或者功能的完善等等都需要找到每個人自己負責的部分進行修補或者更新,那么我們就需要找到那個口袋,
而我們的django項目里面的url配置參數里面,使用到include,后面加上括號,在括號里面可以寫多個url路由系統參數,[我們的django項目會有很多的app,每個小功能都是存放于app里面的,所以我們的app里面的url配置參數都按照每個人負責的部分來進行劃分,放到專屬的include里面]這樣我們就可以很方便的找到自己負責的部分進行操作了
格式是這樣寫的:url(r'^who/',include(aps_urls),? ?-------->我們這里的正則who就相當于是前綴,我們需找到這個前綴下面的aps_urls,然后它里面可以寫很多的url配置參數,我們在include里面只能夠寫一個url配置參數,不可以寫多個,規則就是這樣的,我們要遵守人家的規則,所謂的多個是在aps_urls里面寫多個,而不是在include里面
?
傳遞額外的參數給視圖函數:
URLconfs 具有一個鉤子,讓你傳遞一個Python 字典作為額外的參數傳遞給視圖函數。
django.conf.urls.url()?函數可以接收一個可選的第三個參數,它是一個字典,表示想要傳遞給視圖函數的額外關鍵字參數。
?
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]
?
在此例中,對于/blog/2005/請求中,django將調用views.year_archive(request,year="2005",foo="bar"). 這個技術在syndication框架中使用,來傳遞元數據和選項給視圖
?
?
命名url和url反向解析[官方翻譯版]
在使用django項目是,一個常見的需求是獲得url的最終形式,以用于嵌入到生成的內容中,(視圖中和顯示給用戶的內容)或者用于處理服務器端的導航(重定向等).
我們編碼這些url費力不可擴展同時還容易產生錯誤,如果涉及一種與urlconf不相關的專門的URL生成機制,因為這樣容易導致一定程度上產生過期的url
本質上是需要一個DRY機制,它允許設計的url可以自動更新而不用遍歷項目的源代碼,來搜索并替換過期的url,獲取一個url最開始想到的是信息處理它視圖的標識,查找正確的url的其他必要的信息有視圖參數的類型(位置參數,關鍵字參數)和值,django提供一個辦法是讓url映射是url設計唯一的地方,你填充你的urlconf,然后可以雙向使用它:
根據用戶瀏覽器發起的url請求,它調用正確的django視圖,并從url中提取它的參數需要的值,
根據django視圖的標識和將要傳遞給他的參數的值,獲取與之關聯的url.
第一種方式是我們在前面的章節中一直討論的用法,第二種方式叫做反向解析url反向url匹配,反向url查詢或者簡單的url反查,
在模板中,使用url模板標簽
在python代碼中使用django.core.urlresolvers.reverse()函數.
在高層的與處理django模型實例相關的代碼中,使用get_absolute_url()方法,
=========================================================================
?
簡單來說就是給我們的url匹配規則起個名字,一個url匹配模式起一個名字,這樣我們以后就不需要寫死url代碼了,只需要通過名字來調用當前的url,
例如:
url(r'^home', views.home, name='home'), # 給我的url匹配模式起名為 home url(r'^index/(\d*)', views.index, name='index'), # 給我的url匹配模式起名為index然后在HTML模板里面就這樣引用:{% url'home' %}
在views函數中可以這樣引用:
from django.urls import reverse
reverse("index", args=("2018", ))
考慮下面的urlconf:
from django.conf.urls import url
from . import views
urlpatterns =[
# ...
url(r"^articles/([0-9]{4})/$", views.year_archive, name="news-year-archive'),
#...
根據這里的設計,某一年nnnn對應的歸檔的url是/articles/nnnn/
你可以在這里的模板的代碼中使用下面的方法獲取他們:
<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>
<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
{% endfor %}
</ul>
?
在python代碼中可以這樣使用
from django.urls import reverse
from django.shortcuts import redirect
def redirect_to_year(request):
#...
year = 2005
#...
return redirect(reverse('news-year-archive', args=(year,)))
?
?
?
如果處于某種原因決定按年歸檔文章發布的url應該調整一下,那么你將只需要修改urlconf中的內容,在某些場景中,一個仕途上hi通用的,所以在url和視圖之間存在多對一的關系,對于這些情況,當反查url時,只有視圖的名字還不夠,
注意:
為了完成上面例子中的url反查,你將需要使用命名的url模式,url的名稱使用的字符串可以包含任何你喜歡的字符,不只限制在合法的python名稱,當命名你的url模式時,請確保使用的名稱不會與其他的應用中名稱沖突,如果你的url模式叫做comment而另外一個應用中也有一個同樣的名稱,當你在模板中國使用這個名稱的時候不能保證將插入哪個url.
在url名稱中加上一個前綴,比如應用的名稱,將減少沖突的可能,我們建議使用myapp-comment而不是commet
?
?
?
Django-2.0命名空間模式更新語法
project中的urls.py
from django.conf.urls import url, include
# 官網上的例子# 這是跟setting文件同級目錄的url文件 urls.py from django.urls import include, pathurlpatterns = [path('author-polls/', include('polls.urls', namespace='author-polls')), # 這里的路由隨意設定,include中的第一個參數必須要是app的名字.urls,第二個參數也隨意設定。path('publisher-polls/', include('polls.urls', namespace='publisher-polls')), ]
# 這是app下的URL文件, polls/urls.py from django.urls import pathfrom . import views
# 下面這一行是必須加上的,要有參數“app_name”,參數值建議寫app的名字(當然了,你硬是要瞎寫個別的亂字符串,也不會報錯,只要不是空字符串就行),否則會報錯
“”“
'Specifying a namespace in include() without providing an app_name '
django.core.exceptions.ImproperlyConfigured: Specifying a namespace in include() without providing an app_name is not supported. Set the app_name
attribute in the included module, or pass a 2-tuple containing the list of patterns and app_name instead.
”“” app_name = 'polls' urlpatterns = [path('', views.IndexView.as_view(), name='index'),path('<int:pk>/', views.DetailView.as_view(), name='detail'),... ]?
?
?
模板中引用:
{% url'app01:detail' pk=12 pp=99 %}
?
views中的函數引用
v=reverse('app01:detail', kwargs={'pk':11})
?
?==================================================================================================================================================我們之前寫的那些django項目里面,學生,班級,老師的管理系統,統統都是不規范的,那樣寫僅僅是為了便于我們去理解,其實是有很多的問題的,雖然我們已經理解了,然后還都實現了那些功能,感覺還挺開心的,
======================================================================================================
我們這里把url路由配置和視圖的知識點結合著一起整理到一塊,這樣便于記憶
?
現在我們需要把那些都推翻了,然后以一種更加規范更加合理的方式去寫出來,我們一般的項目都沒有直接寫到我們的django 項目里面的,都是寫到Django項目下面的app里面的,我們的templates是在創建django項目的時候就要自己手動創建好的,用于存放我們的HTML頁面,然后我們創建的那些app就需要根據app的名字把對應的需要用到的那些HTML文件歸類存放,用起來的時候會方便很多,我們命名的時候可以隨意起名,只要你知道你用的時候去哪里找就行,但是為了方便起見一般會給app所對應的那個templates里面的內層文件夾起同樣的名字,跟我們的App的名字一樣,然后我們在views里面寫視圖函數的時候在return部分要渲染HTML頁面,那個頁面我們可以就像之前一樣直接寫HTML的名字,你在運行項目的時候pycharm會自動給你把HTML頁面的前綴加上的,如果我們的templates下面的App對應的文件夾名字有變動的話,pycharm也會自動給你把views視圖里面的return后面的渲染頁面給你自動變更下面有截圖為例:
我們以后不一定就是使用pycharm寫項目,有可能是用其他的軟件去寫項目,所以我們最好是知道這一點然后養成習慣把它加上,畢竟系統是需要這個東西的,不然也不會給你自動增加上
視圖:
我們的路由配置里面(urls.py文件即是)一個url網址對應一個視圖函數,我們的url網址一旦有一丁點的改動都無法執行視圖函數,有一個舉例的場景里面,我們的博客管理系統,我們前面的學生老師班級信息顯示內容都是從數據庫里面取出數據然后把他們提交到前端頁面,這樣的話我們的博客如果數據量巨大的話,我們需要寫海量的復用性極高的代碼,這樣顯然是不科學的,在正常的工作環境中是不可能出現這樣的情況,所以我們不能夠這樣寫
首先我們需要解決url配置的問題,使用正則的話就可以把含有一定規律的url都概括到這樣一個正則里面,我們只要滿足這個正則的要求,就可以正常執行那個url所對應的視圖函數,
?
如下所示:
urlpatterns=[
url(r'^text/$', views.text, name='text'),? # FBV方式 F(function,函數)----B(base,基于)-----V(views, 視圖)======>基于函數的視圖
? 我們在這里解釋一下這個url路由配置的意思,我們之前寫的例子里面就是一個url對應一個視圖函數,我們的r后面是自定義的url網址,后面的views是我們的App里面的views,我們的項目視圖函數都是寫到views里面的,他就是一個路徑的意思,我們之前直接寫到django項目里的時候就是直接把視圖函數里面的函數名寫到這里的,我們有App之后就需要把路徑指定一下,在函數名前面加上App的views路徑,,后面的name才是關鍵的重點,我們的HTML頁面里面的acion里面跳轉的頁面就是使用的name里面的值,就是我們這里的路由配置里面的name里面的值下面有圖,會更易理解一些
]
?
上面使用的是FBV,
在視圖里面還有一個CBV,我們這里來詳解一下,C--class(類)B---base(基于),V---views(視圖)====>基于類的視圖
首先在url配置里面,我們來看一下它是怎么配置的
urlpatterns=[
url(r'^tes/$', aps.Tex.as_view(), name='tet'),? # 這里的as_view() 是對于請求做出判斷,判斷請求是什么方式,它本質就是對于發送過來的請求進行判斷,我們的應用場景是在CBV里面,因為C是class是類,類里面會有很多的方法,我們要在拿到這個請求的時候在這里對其進行判斷,判斷是什么方式然后使用相應的類里面的相應的方法,而我們在FBV里面是不需要使用這一層判斷的,我們的FBV里面只有一個方法,沒得選,我們定義的是什么函數就使用什么函數方法去操作我們的請求,沒有選擇的余地也不需要選擇.
?] # 前面是正則匹配,后面是從app文件路徑里找到函數名,然后后面加上as_view(),這里是CBV里具有的特殊用法,后面的name就是我們上面所寫的方法一樣的,關聯我們的form表單里面的action,動態改變網址
如圖所示:
?
?
分組匹配就不多贅述了,上面有詳解,本身也不是多難的概念
include
還有一個命名空間,以防止命名重復的問題,我們在url里面寫的name的值是不能夠重復的,除非我們可以把他們歸納到一個小范圍里面,就相當于我們的一個一個小組,這個小組里面可以有一個人叫a,但是不能夠在這個組里有重名的,我們有另外一個小組,那個小組里面有一個人叫a,這樣的情況就可以,但是我們的同一個小組里面不能夠有重復的人叫a,這樣的話我們就可以有重復的名字了,至少在大范圍內是可以有重復的
然后我們再反向解析,我們上面一直在重復一件事,就是我們的url里面的那個name所對應的值是我們的HTML里面的form表單里面action所對應的那個需要跳轉的頁面,那個頁面我是寫成了動態的,我們的name是一個總稱,是我們的url路由系統里面正則的總稱,把它放到我們action里面之后,我們拿到這個name就可以去找到我們的正則里面的真實的地址,這里就是反向解析,也就是說我們name的值跟action值所對應的這段關系就是反向解析的過程
?
?
轉載于:https://www.cnblogs.com/2012-dream/p/8306083.html
總結
以上是生活随笔為你收集整理的day64 url用法以及django的路由系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java后台提供ios微信支付接口
- 下一篇: Sqlserver 中的Iif语句