Django URL
一、創(chuàng)建Django項(xiàng)目:
用命令行創(chuàng)建:
創(chuàng)建項(xiàng)目:在終端通過命令:django-admin startproject [項(xiàng)目名稱]?即可創(chuàng)建,比如:django-admin startproject fisher_django
創(chuàng)建應(yīng)用:在終端進(jìn)入到項(xiàng)目所在的路徑,然后執(zhí)行python manage.py startapp [app名稱] 即可創(chuàng)建一個(gè)app
用pycharm創(chuàng)建:
pycharm創(chuàng)建項(xiàng)目后,需重新進(jìn)入到命令行創(chuàng)建app
project和app的關(guān)系:
app是django項(xiàng)目的組成部分,一個(gè)app代表項(xiàng)目中的一個(gè)模塊,所有URL請求的響應(yīng)都是由app來處理
django項(xiàng)目由多個(gè)app組成,一個(gè)app可以被用到其他項(xiàng)目
項(xiàng)目結(jié)構(gòu)介紹:
manage.py:和項(xiàng)目交互的文件,python manage.py [子命令],可通過python manage.py help查看幫助
settings.py:項(xiàng)目的設(shè)置項(xiàng)
urls.py:配置URL路由
wsgi.py:項(xiàng)目與WSGI協(xié)議兼容的web服務(wù)器入口,用于項(xiàng)目部署
運(yùn)行Django項(xiàng)目:
python manage.py runserver,默認(rèn)端口8000
指定端口號python manage.py runserver 9000
若需在其它電腦訪問本站,python manage.py runserver 0.0.0.0:8000
也可通過pycharm運(yùn)行
二、視圖與URL分發(fā)器
URL分發(fā)器
視圖:
視圖一般都寫在app的views.py中。并且視圖的第一個(gè)參數(shù)永遠(yuǎn)都是request(一個(gè)HttpRequest)對象。這個(gè)對象存儲了請求過來的所有信息,包括攜帶的參數(shù)以及一些頭部信息等。在視圖中,一般是完成邏輯相關(guān)的操作。比如這個(gè)請求是添加一篇博客,那么可以通過request來接收到這些數(shù)據(jù),然后存儲到數(shù)據(jù)庫中,最后再把執(zhí)行的結(jié)果返回給瀏覽器。視圖函數(shù)的返回結(jié)果必須是HttpResponseBase對象或者子類的對象。示例代碼如下:
from django.http import HttpResponse def book_list(request): return HttpResponse("書籍列表!")URL映射:
視圖寫完后,要與URL進(jìn)行映射,也即用戶在瀏覽器中輸入什么url的時(shí)候可以請求到這個(gè)視圖函數(shù)。在用戶輸入了某個(gè)url,請求到我們的網(wǎng)站的時(shí)候,django會從項(xiàng)目的urls.py文件中尋找對應(yīng)的視圖。在urls.py文件中有一個(gè)urlpatterns變量,以后django就會從這個(gè)變量中讀取所有的匹配規(guī)則。匹配規(guī)則需要使用django.urls.path函數(shù)進(jìn)行包裹,這個(gè)函數(shù)會根據(jù)傳入的參數(shù)返回URLPattern或者是URLResolver的對象。示例代碼如下:
from django.contrib import admin from django.urls import path from book import views urlpatterns = [ path('admin/', admin.site.urls), path('book/',views.book_list) ]URL中添加參數(shù):
有時(shí)候,url中包含了一些參數(shù)需要?jiǎng)討B(tài)調(diào)整。比如簡書某篇文章的詳情頁的url,是https://www.jianshu.com/p/a5aab9c4978e后面的a5aab9c4978e就是這篇文章的id,那么簡書的文章詳情頁面的url就可以寫成https://www.jianshu.com/p/<id>,其中id就是文章的id。那么如何在django中實(shí)現(xiàn)這種需求呢。這時(shí)候我們可以在path函數(shù)中,使用尖括號的形式來定義一個(gè)參數(shù)。比如我現(xiàn)在想要獲取一本書籍的詳細(xì)信息,那么應(yīng)該在url中指定這個(gè)參數(shù)。示例代碼如下:
from django.contrib import admin from django.urls import path from book import views urlpatterns = [ path('admin/', admin.site.urls), path('book/',views.book_list), path('book/<book_id>/',views.book_detail) ]而views.py中的代碼如下:
def book_detail(request,book_id):text = "您輸入的書籍的id是:%s" % book_id return HttpResponse(text)當(dāng)然,也可以通過查詢字符串的方式傳遞一個(gè)參數(shù)過去。示例代碼如下:
urlpatterns = [path('admin/', admin.site.urls),path('book/',views.book_list),path('book/detail/',views.book_detail) ]在views.py中的代碼如下:
def book_detail(request):book_id = request.GET.get("id") text = "您輸入的書籍id是:%s" % book_id return HttpResponse(text)以后在訪問的時(shí)候就是通過/book/detail/?id=1即可將參數(shù)傳遞過去。
URL中包含另外一個(gè)urls模塊:
在我們的項(xiàng)目中,不可能只有一個(gè)app,如果把所有的app的views中的視圖都放在urls.py中進(jìn)行映射,肯定會讓代碼顯得非常亂。因此django給我們提供了一個(gè)方法,可以在app內(nèi)部包含自己的url匹配規(guī)則,而在項(xiàng)目的urls.py中再統(tǒng)一包含這個(gè)app的urls。使用這個(gè)技術(shù)需要借助include函數(shù)。示例代碼如下:
# first_project/urls.py文件:from django.contrib import admin from django.urls import path,include urlpatterns = [ path('admin/', admin.site.urls), path('book/',include("book.urls")) ]在urls.py文件中把所有的和book這個(gè)app相關(guān)的url都移動到app/urls.py中了,然后在first_project/urls.py中,通過include函數(shù)包含book.urls,以后在請求book相關(guān)的url的時(shí)候都需要加一個(gè)book的前綴。
# book/urls.py文件:from django.urls import path from . import views urlpatterns = [ path('list/',views.book_list), path('detail/<book_id>/',views.book_detail) ]以后訪問書的列表的url的時(shí)候,就通過/book/list/來訪問,訪問書籍詳情頁面的url的時(shí)候就通過book/detail/<id>來訪問。
path函數(shù):
path函數(shù)的定義為:path(route,view,name=None,kwargs=None)。以下對這幾個(gè)參數(shù)進(jìn)行講解。
route參數(shù):url的匹配規(guī)則。這個(gè)參數(shù)中可以指定url中需要傳遞的參數(shù),比如在訪問文章詳情頁的時(shí)候,可以傳遞一個(gè)id。傳遞參數(shù)是通過<>尖括號來進(jìn)行指定的。并且在傳遞參數(shù)的時(shí)候,可以指定這個(gè)參數(shù)的數(shù)據(jù)類型,比如文章的id都是int類型,那么可以這樣寫<int:id>,以后匹配的時(shí)候,就只會匹配到id為int類型的url,而不會匹配其他的url,并且在視圖函數(shù)中獲取這個(gè)參數(shù)的時(shí)候,就已經(jīng)被轉(zhuǎn)換成一個(gè)int類型了。其中還有幾種常用的類型:
- str:非空的字符串類型。默認(rèn)的轉(zhuǎn)換器。但是不能包含斜杠。
- int:匹配任意的零或者正數(shù)的整形。到視圖函數(shù)中就是一個(gè)int類型。
- slug:由英文中的橫杠-,或者下劃線_連接英文字符或者數(shù)字而成的字符串。
- uuid:匹配uuid字符串。
- path:匹配非空的英文字符串,可以包含斜杠。
view參數(shù):可以為一個(gè)視圖函數(shù)或者是類視圖.as_view()或者是django.urls.include()函數(shù)的返回值。
name參數(shù):這個(gè)參數(shù)是給這個(gè)url取個(gè)名字的,這在項(xiàng)目比較大,url比較多的時(shí)候用處很大。
kwargs參數(shù):有時(shí)候想給視圖函數(shù)傳遞一些額外的參數(shù),就可以通過kwargs參數(shù)進(jìn)行傳遞。這個(gè)參數(shù)接收一個(gè)字典。傳到視圖函數(shù)中的時(shí)候,會作為一個(gè)關(guān)鍵字參數(shù)傳過去。比如以下的url規(guī)則:
from django.urls import pathfrom . import viewsurlpatterns = [path('blog/<int:year>/', views.year_archive, {'foo': 'bar'}), ]那么以后在訪問blog/1991/這個(gè)url的時(shí)候,會將foo=bar作為關(guān)鍵字參數(shù)傳給year_archive函數(shù)。
re_path函數(shù):
有時(shí)候我們在寫url匹配的時(shí)候,想要寫使用正則表達(dá)式來實(shí)現(xiàn)一些復(fù)雜的需求,那么這時(shí)候我們可以使用re_path來實(shí)現(xiàn)。re_path的參數(shù)和path參數(shù)一模一樣,只不過第一個(gè)參數(shù)也就是route參數(shù)可以為一個(gè)正則表達(dá)式。
一些使用re_path的示例代碼如下:
以上例子中我們可以看到,所有的route字符串前面都加了一個(gè)r,表示這個(gè)字符串是一個(gè)原生字符串。在寫正則表達(dá)式中是推薦使用原生字符串的,這樣可以避免在python這一層面進(jìn)行轉(zhuǎn)義。而且,使用正則表達(dá)式捕獲參數(shù)的時(shí)候,是用一個(gè)圓括號進(jìn)行包裹,然后這個(gè)參數(shù)的名字是通過尖括號<year>進(jìn)行包裹,之后才是寫正則表達(dá)式的語法。
include函數(shù):
在項(xiàng)目變大以后,經(jīng)常不會把所有的url匹配規(guī)則都放在項(xiàng)目的urls.py文件中,而是每個(gè)app都有自己的urls.py文件,在這個(gè)文件中存儲的都是當(dāng)前這個(gè)app的所有url匹配規(guī)則。然后再統(tǒng)一注冊到項(xiàng)目的urls.py文件中。include函數(shù)有多種用法,這里講下兩種常用的用法。
include(pattern,namespace=None):直接把其他app的urls包含進(jìn)來。示例代碼如下:
from django.contrib import adminfrom django.urls import path,includeurlpatterns = [path('admin/', admin.site.urls), path('book/',include("book.urls")) ]當(dāng)然也可以傳遞namespace參數(shù)來指定一個(gè)實(shí)例命名空間,但是在使用實(shí)例命名空間之前,必須先指定一個(gè)應(yīng)用命名空間。示例代碼如下:
# 主urls.py文件: from django.urls import path,include urlpatterns = [path('movie/',include('movie.urls',namespace='movie')) ]然后在movie/urls.py中指定應(yīng)用命名空間。實(shí)例代碼如下:
from django.urls import path from . import views# 應(yīng)用命名空間 app_name = 'movie' urlpatterns = [ path('',views.movie,name='index'), path('list/',views.movie_list,name='list'), ]include(pattern_list):可以包含一個(gè)列表或者一個(gè)元組,這個(gè)元組或者列表中又包含的是path或者是re_path函數(shù)。
include((pattern,app_namespace),namespace=None):在包含某個(gè)app的urls的時(shí)候,可以指定命名空間,這樣做的目的是為了防止不同的app下出現(xiàn)相同的url,這時(shí)候就可以通過命名空間進(jìn)行區(qū)分。示例代碼如下:
from django.contrib import adminfrom django.urls import path,includeurlpatterns = [path('admin/', admin.site.urls), path('book/',include(("book.urls",'book')),namespace='book') ]但是這樣做的前提是已經(jīng)包含了應(yīng)用命名空間。即在myapp.urls.py中添加一個(gè)和urlpatterns同級別的變量app_name。
指定默認(rèn)的參數(shù):
使用path或者是re_path的后,在route中都可以包含參數(shù),而有時(shí)候想指定默認(rèn)的參數(shù),這時(shí)候可以通過以下方式來完成。示例代碼如下:
from django.urls import pathfrom . import viewsurlpatterns = [path('blog/', views.page), path('blog/page<int:num>/', views.page), ] # View (in blog/views.py) def page(request, num=1): # Output the appropriate page of blog entries, according to num. ...當(dāng)在訪問blog/的時(shí)候,因?yàn)闆]有傳遞num參數(shù),所以會匹配到第一個(gè)url,這時(shí)候就執(zhí)行view.page這個(gè)視圖函數(shù),而在page函數(shù)中,又有num=1這個(gè)默認(rèn)參數(shù)。因此這時(shí)候就可以不用傳遞參數(shù)。而如果訪問blog/1的時(shí)候,因?yàn)樵趥鬟f參數(shù)的時(shí)候傳遞了num,因此會匹配到第二個(gè)url,這時(shí)候也會執(zhí)行views.page,然后把傳遞進(jìn)來的參數(shù)傳給page函數(shù)中的num。
url反轉(zhuǎn):
之前我們都是通過url來訪問視圖函數(shù)。有時(shí)候我們知道這個(gè)視圖函數(shù),但是想反轉(zhuǎn)回他的url。這時(shí)候就可以通過reverse來實(shí)現(xiàn)。示例代碼如下:
reverse("list") > /book/list/如果有應(yīng)用命名空間或者有實(shí)例命名空間,那么應(yīng)該在反轉(zhuǎn)的時(shí)候加上命名空間。示例代碼如下:
reverse('book:list') > /book/list/如果這個(gè)url中需要傳遞參數(shù),那么可以通過kwargs來傳遞參數(shù)。示例代碼如下:
reverse("book:detail",kwargs={"book_id":1}) > /book/detail/1因?yàn)閐jango中的reverse反轉(zhuǎn)url的時(shí)候不區(qū)分GET請求和POST請求,因此不能在反轉(zhuǎn)的時(shí)候添加查詢字符串的參數(shù)。如果想要添加查詢字符串的參數(shù),只能手動的添加。示例代碼如下:
login_url = reverse('login') + "?next=/"自定義URL轉(zhuǎn)換器:
之前已經(jīng)學(xué)到過一些django內(nèi)置的url轉(zhuǎn)換器,包括有int、uuid等。有時(shí)候這些內(nèi)置的url轉(zhuǎn)換器并不能滿足我們的需求,因此django給我們提供了一個(gè)接口可以讓我們自己定義自己的url轉(zhuǎn)換器。
自定義url轉(zhuǎn)換器按照以下五個(gè)步驟來走就可以了:
比如寫一個(gè)匹配四個(gè)數(shù)字年份的url轉(zhuǎn)換器。示例代碼如下:
# 1. 定義一個(gè)類class FourDigitYearConverter:# 2. 定義一個(gè)正則表達(dá)式 regex = '[0-9]{4}' # 3. 定義to_python方法 def to_python(self, value): return int(value) # 4. 定義to_url方法 def to_url(self, value): return '%04d' % value # 5. 注冊到django中 from django.urls import register_converter register_converter(converters.FourDigitYearConverter, 'yyyy') urlpatterns = [ path('articles/2003/', views.special_case_2003), # 使用注冊的轉(zhuǎn)換器 path('articles/<yyyy:year>/', views.year_archive), ... ]轉(zhuǎn)載于:https://www.cnblogs.com/fisherbook/p/11067885.html
總結(jié)
以上是生活随笔為你收集整理的Django URL的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Ubuntu上安装openResty
- 下一篇: No changes detected