1. url的複習
網址 全球統一資源定位符
格式 協議(http,HTTPS,ftp等)+域名(ip地址和端口)+路徑+參數
2.django的路由系統
當一個請求來到時
1.首先到項目目錄下的urls.py (根URLconf模塊)中,查找路由規則
2.根URLconf模塊,裏面定義了 urlpatterns 變量
3.urlpatterns 是一個(django.urls.path,django.urls.re_path 對象)列表 其中django.urls.path和django.urls.re_path都是django中的方法
4.按順序運行每一個url模式,在第一個匹配的模式中止
5.一旦匹配,django導入並調用給定的視圖
6.若是中間出錯,或者沒有匹配到,返回404
-path(route, view, kwargs=None, name=None)
- route 是一個字符串的url規則
- view 是個視圖,表示給定的路徑會調用的視圖,寫上調用的方法,不要加括號
- kwargs 不是不定長參數,而是額外參數,傳遞給view,必須是一個字典
- name url的命名
前兩個參數是必須的
- 在url中捕獲參數
在url規則中使用`<變量名>`能夠捕獲url中的值,注意是寫在前邊的route裏,路徑後邊好比'detail/<變量名>/',url的route裏的參數,要和views裏的方法裏的參數一 一對應,html
urlpatterns = [ path('home/', views.index, name='index'), path('detail/<int:pk>/', views.detail, kwargs={'status': True}), re_path(r'students/(?P<year>\d{4})/(?P<month>[0-9]|1[0-2])/', views.students), path('login/', views.login) ]
多個參數 1)views.py中的函數裏,加上其餘參數,在urls中的路由方法裏,detail/<變量名1>/<變量名2>/,變量1,2的順序能夠換,可是訪問頁面的時候在瀏覽器中傳參要按照urls中設置的順序
2)參數之間也能夠不用/,能夠用鏈接符-,訪問網頁的時候在瀏覽器中輸入的url的參數之間也要用鏈接符,別的符號連接也能夠,好比+,~,,(注意這裏,也能夠),.,[等前端
def detail(request,pk,status):#pk是主鍵 return HttpResponse("離開學還有%s天,你做業作完沒,道路千萬條,學習第一條,做業沒寫完,開學兩行淚!" % pk) def students(request,year,month): return HttpResponse("%s年%s月報名的學生列表" % (year, month))
傳遞給視圖 ,匹配了url以後調用視圖的時候傳遞給視圖的是關鍵字參數,url路徑中不分組則按照位置參數傳
** 捕獲的值是 字符串 url中域名後邊的東西,會被傳遞到urls的urlpatterns裏邊對應的路徑方法中,
- 路徑轉換器 限制傳遞進來的參數,也是寫在urlpatterns裏的路徑裏,它限制了url傳進來的參數,必須是路徑轉換器設置的數據類型(試過了能轉換成該類型的數據類型也不能夠,必須得是那個數據類型),而且從路徑傳給視圖的參數的類型就是路徑中規定的數據類型
案例:<int:pk>python
path('detail/<int:pk>/', views.detail, kwargs={'status': True}),
經常使用的轉換器:
- str 匹配除了‘/'路徑分隔符以外的全部字符串
- int 匹配任意整數
- slug 匹配任意ascii字符 加上連字符和下劃線
- uuid 格式化id,通用惟一識別碼(Universally Unique Identifier)的縮寫UUID是指在一臺機器上生成的數字,
它保證對在同一時空中的全部機器都是惟一的。一般平臺會提供生成的API。按照開放軟件基金會(OSF)制定的標準計算,用到了以太網卡地址、納秒級時間、芯片ID碼和隨機數。
- path 匹配任意非空字符
- 使用正則表達式 re_path(route, view, kwargs=None, name=None),首先要導入re_path()模塊,寫在上邊的from django.urls import path的path後面就能夠了
在views裏和上面同樣,在瀏覽器中輸入url時,參數也是那樣傳遞,
在urlpatterns裏面,方法不是path(),要用re_path(),第一個參數的引號前加r,r""
python 中 正則表達式的分組命名 (?<name>pattern) 具體例子是r'(?P<year>\d{4})'或者4個\d,而後/(?P<month>[0-9]|1[0-2])/,連起來就是re_path(r'(students/(?P<year>\d{4})/(?P<month>[0-9]|1[0-2])/',views.students)
正則表達式
re_path(r'students/(?P<year>\d{4})/(?P<month>[0-9]|1[0-2])/', views.students),
- django 搜索 url 搜索的是什麼?
只搜索路徑部分,跟參數,以及請求方法(get,post)無關
同一個url 能夠匹配 get, post
- 包含其餘URLconfs:通常不多把視圖函數寫在公共的項目文件夾下,通常寫在app裏,如何指定app中的路徑,須要在app中新建urls.py,而後在項目文件夾的urls.py中
include: 1)導入:在導入path和re_path後加上include
2)項目中的urls去定義app中的urls :在項目文件夾的urls.py中的urlpatterns加上path("appname/",include('appname.urls')),
注意include裏的文件名後面的.urls是你在app文件夾中建立的那個,也能夠不叫urls,可是最好叫urls,appname.urls要加引號括起來
3)在app的urls.py中的urlpatterns中,先導入:from django.urls import path,re_path後加上include,以及from . import views
4)定義path()或re_path(),視圖函數的相對路徑也是和urls文件平級的
5)運行後瀏覽器訪問的時候url中的路徑 要先寫appname而後/app中的視圖函數
原理,訪問的時候url先通過根urls.py,匹配到appname,先切掉appname的部分,剩下的傳到include裏邊的appname.urls裏,在那裏面匹配剩下的,
前邊的路由若是傳進來參數,也是能夠傳遞到include裏邊的,在include裏邊對應的app.urls中繼續匹配路徑,匹配到以後傳遞給app中相應的視圖函數,
這樣在根urls中設置了"appname-<參數>/"會傳給app中的每一個路徑,若是在相應app的視圖函數中沒有參數接收他就會報錯
- 傳遞額外參數
1path,re_path 方法中,傳遞一個kwargs 的字典參數,傳遞給視圖函數,不能urls中定義了額外參數而在視圖函數中沒有參數接收他
2***** 當kwargs 中的key 與 url捕獲中的key 一致的時候,以kwargs爲準,好比path('detail/<int:pk>/',views.detail,kwargs={'pk':10}),若是訪問網址中輸入別的數字,最終傳給視圖函數的仍是10
3若是在項目文件夾的urls中的include路徑中加上kwargs={'somekey':"somevalue"},就會把這個額外參數傳遞給該app的每一個視圖函數,至關於給app中的urls中的每一個路徑加上kwargs={'somekey':"somevalue"}django
path('detail/<int:pk>/', views.detail, kwargs={'status': True}),
- url 命名
頁面重定向 ,跳轉頁面(響應狀態碼301) 登陸以後, 某個操做以後,django中提供了一個方法redirect,能接收url,返回一個重定向的響應,而後頁面就會重定向
好比在視圖函數中,return redirect('http://www.baidu.com')返回重定向的url,也就是在訪問該視圖時,會自動重定向到指定的url,能夠用於登錄頁面,
redirect中也能夠「/appname/index/」這裏要把相對路徑寫全,前邊也要有/,後面也要有/,可是若是想給路由中的url路徑更名,重定向的地方都要改,這樣是硬編碼,url命名是爲了不硬編碼
在urls.py中urlpatterns中的指定path中加一個name參數 給更名後的url起個名字瀏覽器
path('home/', views.index, name='index'),
再在views.py中導入reverse方法,就能夠經過這個url的名字反向的解析路由,解析出url,導入後在視圖函數中加上url = reverse('index'),返回時return redirect(url),這時候reverse方法會把該url反向解析成urls中給定的path中的全路徑app
from django.shortcuts import render,redirect,reverse def login(request): url = reverse("app1:index") return redirect(url)
- app_name 同一項目下app名不能重複
定義在 app文件夾下的urlconf模塊中,就是每一個app文件夾下urls.py裏,都分別加上app_name = app名稱,函數
app_name = 'app1'
而後在各自views裏的reverse('appname:index')post
def login(request): url = reverse("app1:index") return redirect(url)
若是有多個app都有同名的跳轉,則根目錄解析時候會調用最後一個include的視圖函數,因此必須給每一個app起名字
3. 模板系統
html 源碼寫到模板文件中
- 模板路徑設置
1)通常模板是放在項目的根目錄下的,新建一個templates文件夾,而後配置settings.py
2)settings裏面設置 TEMPLATES,這是一個dict:
'BACKEND':'django.template.backends.django.DjangoTemplates'是模板的引擎,是後臺
‘DIRS’:[]是模板的路徑,模板渲染的設置就是要搞它,
3)先在settings.py中導入os模塊,注意settings.py有一行BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 用來取到項目的根目錄
4)在 TEMPLATES中的DIRS這個鍵的值的列表裏邊,添加拼接路徑os.path.join(BASE_DIR,'templates')告訴django模板從這個文件夾裏找,動態獲取templates文件夾的路徑,學習
'DIRS': [os.path.join(BASE_DIR,'templates')],
若是打印os.path.join(BASE_DIR,'templates'),獲得的是從home目錄開始到templates的絕對路徑
其實放模板的文件夾起其餘名字也能夠,可是起好名字settings裏設置的時候就要用它,不要寫錯
5)在templates文件夾中,爲想添加模板的app設置各自的文件夾,好比新建一個teacher文件夾,而後在這個文件夾裏新建HTML File文檔,命名index,編寫前端代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>app1_index</title> </head> <body> <h1>我是app1中的主頁面</h1> <form action=""> <p>用戶名: <input type="text"></p> <p>密碼: <input type="password"></p> <p><input type="submit" value="登錄"></p> </form> </body> </html>
6)在指定的視圖中想拿到爲它編寫的模板 首先from django.template.loader import get_template
7) 在指定的視圖函數中定義tp = get_template('teacher/index.html')也就是說templates不用寫,從它裏邊的路徑開始寫到想要的html文件就能夠,django會默認幫咱們把前邊路徑補上
8)渲染模板 html = tp.render() render是調用的方法,獲得的是一個模板所定義的html文檔的一整個字符串
9)將html返回出去 return HttpResponse(html)
10)推薦使用快捷方式:省掉步驟從7到9,直接return render(request,'teacher/index.html')
def index(request): return render(request, 'app1/html1.html')