Django初始和url路由機制

一.Django下載安裝

django官網
1.下載django:

pip3 install django==1.11.9

2.創建項目:

django-admin startproject books

在這裏插入圖片描述
manage.py ----- Django項目裏面的工具,通過它可以調用django shell和數據庫,啓動關閉項目與項目交互等,不管你將框架分了幾個文件,必然有一個啓動文件,其實他們本身就是一個文件。
settings.py ---- 包含了項目的默認設置,包括數據庫信息,調試標誌以及其他一些工作的變量。
urls.py ----- 負責把URL模式映射到應用程序。
wsgi.py ---- runserver命令就使用wsgiref模塊做簡單的web server,後面會看到renserver命令,所有與socket相關的內容都在這個文件裏面了,目前不需要關注它。
3.啓動項目
python3 manage runserver 127.0.0.1:8080 #本機就不用寫ip地址了 默認是8000端口
啓動成功後默認是英文的,如果想切換成中文可以在settings.py文件中將
LANGUAGE_CODE = 'en-us’改爲:LANGUAGE_CODE = 'zh-Hans’
在這裏插入圖片描述
面我們只是創建了一個項目,並沒有創建應用,以微信來舉例,微信是不是一個大的項目,但是微信裏面是不是有很多個應用,支付應用、聊天應用、朋友圈、小程序等這些在一定程度上都是相互獨立的應用,也就是說一個大的項目裏面可以有多個應用,也就是說項目是包含應用的,它沒有將view放到這個項目目錄裏面是因爲它覺得,一個項目裏面可以有多個應用,而每個應用都有自己這個應用的邏輯內容,所以他覺得這個view應該放到應用裏面,比如說我們的微信,剛纔說了幾個應用,這幾個應用的邏輯能放到一起嗎,放到一起是不是就亂套啦,也不好管理和維護,所以這些應用的邏輯都分開來放,它就幫我們提煉出來了,提煉出來一個叫做應用的東西,所以我們需要來創建這個應用。
4.創建應用

python3 manage.py startapp app01

在這裏插入圖片描述
models.py :之前我們寫的那個名爲model的文件就是創建表用的,這個文件就是存放與該app(應用)相關的表結構的
views.py :存放與該app相關的視圖函數的
5.django請求生命週期
在這裏插入圖片描述
通過django的請求流程中我們可以看到一個請求過來第一步先走我們的wsgi.py,這是django給我們封裝好的,我們不用管它,下面是中間件,這個我們後續再學,然後走我們的url,首先我們先配置一個我們的url路徑,在我們創建好的項目下面有一個urls.py這個文件,路徑就是在這個裏面配置的:
在這裏插入圖片描述
url中第一個參數是我們的要訪問的url路徑,第二個參數是我們對應的視圖函數,這時我們就要寫我們的視圖函數了:
在這裏插入圖片描述
啓動項目,在瀏覽器中輸入我們的路徑,自己配的是什麼路勁就寫什麼路徑:
在這裏插入圖片描述
6.Templates模板
上面是請求index這個路勁django給瀏覽器返回一個字符串‘你好’,如果我們想給用戶返回一個頁面就需要用到我們的模板templates,直接在我們的項目下新建一個templates文件夾,名稱不要寫錯。
在這裏插入圖片描述
下面就是寫我們的HTML頁面了,
在這裏插入圖片描述
7.get請求獲取數據
get數據都在request.get裏面
在這裏插入圖片描述
8.post請求獲取數據
post數據都在request.POST裏面
在這裏插入圖片描述
還有一點:post請求的時候你會發現一個 Forbidden的錯誤:
在這裏插入圖片描述
需要在settings配置文件裏面將這一行註釋掉,這是django給你加的一個csrf的認證,後續會講:
在這裏插入圖片描述
django寫視圖函數的時候,有一個參數是必須要給的叫做request,如果你是post請求,那麼就用request.POST,就能拿到post請求提交過來的所有數據(一個字典,然後再通過字典取值request.POST.get(‘username’),取出來的就是個字符串,你在那個字典裏面看到的是{‘username’:[‘test’]},雖然看着是列表,但是request.POST.get(‘username’)取出來的就是個字符串),通過request.GET就能拿到提交過來的所有數據,而且記着,每一個視圖函數都要給人家返回一些內容,用render或者HttpResponse等,其實render裏面也是通過HttpResponse來返回內容,不然會報錯,錯誤是告訴你沒有返回任何內容:
在這裏插入圖片描述

二.命名URL(別名)

1.無名分組
基本格式:正則表達式, views視圖函數,參數,別名
在這裏插入圖片描述
參數說明:
正則表達式:一個正則表達式字符串
views視圖函數:一個可調用對象,通常爲一個視圖函數或一個指定視圖函數路徑的字符串
參數:可選的要傳遞給視圖函數的默認參數(字典形式)
別名:一個可選的name參數

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
    url(r'^books/2000/$', views.book), #如果用戶想看2004、2005、2006....等,你要寫一堆的url嗎,是不是在articles後面寫一個正則表達式/d{4}/就行啦,網址裏面輸入127.0.0.1:8000/articles/1999/試一下看看
    url(r'^books/(\d{4})/$', views.book), #無名分組
    url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), #思考,如果你想拿到用戶輸入的什麼年份,並通過這個年份去數據庫裏面匹配對應年份的文章,你怎麼辦?怎麼獲取用戶輸入的年份啊,分組/(\d{4})/,一個小括號搞定
    url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

views.py中的寫法:
第一個參數必須是request,後面跟的三個參數是對應着上面分組正則匹配的每個參數的

def article_detail(request,year,month,day):
    return HttpResponse(year+month+day)

2.有名分組

   url(r'^books/(\d{4})/$', views.year_book),  # 匹配年份
   url(r'^books/(?P<year>\d{4})/(?P<month>\d{1,2})', views.year_month_book),  # 匹配年份和月份

views.py文件中寫法:

有名分組:參數一定要和url路由中的名字一樣
def year_month_books(request, year, month):  # 必須要和urls.py中的名字相同 參數位置無關緊要
    return HttpResponse(year + '  ' + month)

這裏需要注意一個點:
如果我們請求的時候將url後面的斜槓/去掉http://127.0.0.1:8000/books/2002/12,在控制檯裏面我們可以看到是發了兩次請求的,第一個請求是301重定向請求,這就是django定義的你訪問我的路徑的時候後面必須加/斜槓,如果沒加django就自動給你發一個重定向請求,瀏覽器加上這個斜槓再繼續訪問。
在這裏插入圖片描述
如果我們想去掉django這個機制,可以在settings.py文件中加上:

APPEND_SLASH=False  ##不讓django加斜槓 默認是True

3.視圖函數中指定默認值

urls.py文件中:
 	#默認值參數
    url(r'^books/$', views.books),  
    url(r'^books/(?P<num>\d{4})/', views.books), 
views.py文件中:
	def books(request,num=10):
    print(num)
    return HttpResponse(num)

在上面的例子中,兩個URL模式指向相同的view - views.books- 但是第一個模式並沒有從URL中捕獲任何東西。
如果第一個模式匹配上了,page()函數將使用其默認參數num=“1”,如果第二個模式匹配,page()將使用正則表達式捕獲到的num值。

4.include路由分發
views和models文件是不是都放在每一個app應用裏面了啊,而urls.py這個文件放在哪了,是不是放在項目文件夾裏面了,說明什麼,說明是不是所有的app都在使用它,如果你一個項目有10個應用,每個應用有100個url,那意味着你要在urls文件裏面要寫多少條url對應關係,並且所有的app的url都寫在了這一個urls文件裏面啊,這樣好嗎,當然也沒有問題,但是耦合程度太高了,所以django在url這裏給你提供了一個分發接口,叫做include:

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # include
    url(r'', views.index),
    url(r'^app01/', include('app01.urls',namespace='app1')),  #app01應用
    url(r'^app02/', include('app02.urls',namespace='app2')),  #app02應用
    url(r'^base/', views.base),
]

每個應用下面創建一個urls.py文件,裏面可以放對應我們這個應用的url路徑:
在這裏插入圖片描述
include中的namespace參數解釋:
url(r’^app01/’, include(‘app01.urls’,namespace=‘app1’)),
第一個參數是str,對應的就是我們應用名稱下面的urls,第二個參數叫做名稱空間namespace,這裏主要是區分我們的全局變量name,考慮一下如果我們兩個APP應用下面都有index這個視圖函數,那請求的時候到底是請求的app01還是APP02呢,你會發現,不管你是訪問app01下的index還是app02下的index,打印的結果都是/app02/index/,也就是打印的是最後一個index別名對應的url路徑。所以別名衝突了的話就需要我們的命名空間來保證別名對應的url的唯一性了,這個時候就需要namespace這個參數來指定,這個時候我們的應用裏面的寫法就要變了:
應用app01:

from django.conf.urls import url
from app01 import views
app_name = 'app1'
urlpatterns = [
    url(r'^$', views.index,name='index'),
]

應用APP02:

from django.conf.urls import url
from app02 import views
app_name = 'app2'
urlpatterns = [
    url(r'^$', views.index,name='index'),
]

這裏需要注意一點:
django1.x版本中需要定義一個app_name=‘名稱空間’,但是在2.x版本中可以簡寫爲:
url(r’^$’, views.index,name=‘名稱空間:index’) #django2.x版本中的寫法.

首頁問題
現在我輸入http://127.0.0.1:8000來查看網站的首頁,怎麼辦,也就是說我後面不加任何路徑,就看你網址的首頁,一般網站的根路徑都是網站的首頁,我們直接訪問根路徑肯定訪問不到:
在這裏插入圖片描述
提示信息裏面會告訴你那些是可用的路徑,可以看我們下面的寫法可不可以:

url(r'', views.index),  #這裏什麼也不寫
url(r'^app01/', include('app01.urls',namespace='app1')),
url(r'^app02/', include('app02.urls',namespace='app2')),
url(r'^base/', views.base),

在這裏插入圖片描述
這下我們就可以匹配到了,但是考慮一下,如果我們這樣寫的話url(r’’, views.index)意思就是匹配全部,後面的所有url到這裏就攔截了,但是我們還有其他的路徑要匹配,這個時候怎麼辦,其實可以放在下面:

url(r'^app01/', include('app01.urls',namespace='app1')),
url(r'^app02/', include('app02.urls',namespace='app2')),
url(r'^base/', views.base),
url(r'', views.index),

在這裏插入圖片描述
爲什麼放在最下面就可以了,這裏需要解釋一下,django匹配我們路徑的時候會循環我們的urlpatterns,循環判斷我們寫的正則正則表達式,一旦匹配成功則不再繼續:
僞代碼:

for url in urlpatterns:
	ret = re.match('^books/(\d{4})/','books/2002/12/')
	if ret:
		break

這個時候就可以匹配到我們的其他路徑了,但是這樣寫也不太嚴謹,最正確的寫法:
url(r’^$’, views.index),#以空開頭,還要以空結尾,寫在項目的urls.py文件裏面就是項目的首頁,寫在應用文件夾裏面的urls.py文件中,那就是app01的首頁。
在這裏插入圖片描述

三.url反向解析

你想,我們自己寫的url裏面的路徑有沒有可能會更改,如果路徑更改了,那麼我們前端訪問這個路徑的標籤(a標籤,form表單等等)裏面的屬性值是不是也要自己手動去改啊,這樣我們拓展起來就不方便了,你想是不是?尤其是前端可能不是你寫的,那你是不是要進行部門溝通啊,想一想怎麼辦?
在使用Django 項目時,一個常見的需求是獲得URL的最終形式,以用於嵌入到生成的內容中(視圖中和顯示給用戶的URL等)或者用於處理服務器端的導航(重定向等)。
人們強烈希望不要硬編碼(其實就是在標籤裏面寫死了路徑,凡是寫死了的代碼就是硬編碼)這些URL(費力、不可擴展且容易產生錯誤)或者設計一種與URLconf 毫不相關的專門的URL 生成機制,因爲這樣容易導致一定程度上產生過期的URL。
換句話講,需要的是一個DRY 機制。除了其它有點,它還允許設計的URL 可以自動更新而不用遍歷項目的源代碼來搜索並替換過期的URL。
獲取一個URL 最開始想到的信息是處理它視圖的標識(例如名字),查找正確的URL 的其它必要的信息有視圖參數的類型(位置參數、關鍵字參數)和值。
Django 提供一個辦法是讓URL 映射是URL 設計唯一的地方。你填充你的URLconf,然後可以雙向使用它:
根據用戶/瀏覽器發起的URL 請求,它調用正確的Django 視圖,並從URL 中提取它的參數需要的值。
根據Django 視圖的標識和將要傳遞給它的參數的值,獲取與之關聯的URL。
第一種方式是我們在前面的章節中一直討論的用法。第二種方式叫做反向解析URL、反向URL 匹配、反向URL 查詢或者簡單的URL 反查。
在需要URL 的地方,對於不同層級,Django 提供不同的工具用於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

模板裏面可以這樣寫:
在這裏插入圖片描述
views.py可以這樣寫:
在這裏插入圖片描述
或者直接return redirect(‘app1:index’) redirect內部會自動調用reverse來進行反向解析。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章