day053Django基礎之url控制器、視圖函數、模板

本節內容: 一、Django簡單示例 二、MTV之url控制器 三、MTV之視圖函數 四、MTV之模板 1、Django的簡單示例 一、須要知道的一些關鍵點 1 Django項目不管多大,只是一個應用程序 2 地址欄發請求默認是:一、GET請求 二、form表單能夠發送get請求,也能夠發送post請求 三、 標籤也能夠發送請求 3 瀏覽器接受的響應體是字符串,由瀏覽器解釋渲染成頁面給用戶看 4 form表單的提交按鈕事件: 給action對應的服務器發送請求 '' GET /auth/?數據user=yuan&pwd=123 .... ...... ...... 空行 請求體 # user=yuan&pwd=123 '' 5 新的響應會覆蓋以前請求的響應頁面 二、Django的簡單示例 寫代碼的順序就按文件的順序 urls.py代碼 from django.contrib import admin from django.urls import path,re_path from app01 import views # 引入視圖模塊 urlpatterns = [ path('admin/', admin.site.urls), path('index/', views.index), path('login/', views.login), ] PythonCopy views.py代碼示例 from django.shortcuts import render,HttpResponse,redirect # 響應體三劍客 # Create your views here. def login(request): if request.method=="GET": return render(request,"login.html") else: # request :包含全部請求信息 # 獲取請求信息 print("body", request.body) # 請求體原生數據 print(request.method) # "POST" 請求方式 print(request.path) # "/auth/" 拿到路徑 print(request.GET) # print(request.POST) # user = request.POST.get("user") pwd = request.POST.get("pwd") print("user", user) if user == "alex" and pwd == "123": return redirect("/index/") # 這樣這裏寫死了代碼 return HttpResponse("Error!") PythonCopy login.html代碼示例 Title
用戶名 密碼
HTMLCopy 2、路由控制器 本質是URL與要爲該URL調用的視圖函數之間的映射表,就是以這種方式告訴Django, 對於客戶端發來的某個URL調用哪一段邏輯代碼對應執行。 (這裏注意使用反向解析,能夠實現動態修改訪問路徑) 這裏的執行順序: 一、拿着path(路徑:IP地址或域名,以後的,?號以前的,這中間這一截,/index/), 二、在urls.py的urlpatterns的列表中進行比對,比對成功 三、執行對應的視圖函數, 四、視圖函數返回響應給瀏覽器 一、簡單的使用 相應代碼示例 urls.py文件 from django.urls import path,re_path from app01 import views urlpatterns = [ # 從上往下匹配,(先後條件均可以匹配成功的話)若是前面的先匹配,後面的就不會再匹配, re_path(r'^articles/2003/$', views.special_case_2003), # special_case_2003(request) re_path(r'^articles/([0-9]{4})/$', views.year_archive), # year_archive(request,1999) re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), re_path(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail), ] 相應的解釋: /articles/2005/03/ 請求將匹配列表中的第三個模式。Django 將調用函數views.month_archive(request, '2005', '03')。 /articles/2005/3/ 不匹配任何URL 模式,由於列表中的第三個模式要求月份應該是兩個數字。 /articles/2003/ 將匹配列表中的第一個模式不是第二個,由於模式按順序匹配,第一個會首先測試是否匹配。 請像這樣自由插入一些特殊的狀況來探測匹配的次序。 /articles/2003 不匹配任何一個模式,由於每一個模式要求URL 以一個反斜線結尾。 /articles/2003/03/03/ 將匹配最後一個模式。Django 將調用函數views.article_detail(request, '2003', '03', '03')。 PythonCopy 注意: 一、若要從URL 中捕獲一個值,只須要在它周圍放置一對圓括號。 二、不須要添加一個前導的反斜槓,由於每一個URL 都有。 例如,應該是^articles 而不是 ^/articles。 三、每一個正則表達式前面的'r' 是可選的可是建議加上。 它告訴Python 這個字符串是「原始的」 —— 字符串中任何字符都不該該轉義 二、分組(目的:傳參給view函數) 上面的示例使用簡單的、沒有命名的正則表達式組(經過圓括號) 來捕獲URL 中的值並以位置 參數傳遞給視圖。 在更高級的用法中,可使用命名的正則表達式組來捕獲URL 中的值並以關鍵字 參數傳遞給視圖。 在Python 正則表達式中,(這個是1版本的寫法,2版本默認有首尾的正則限定,不用寫) 命名正則表達式組的語法是(?P pattern), 其中name 是組的名稱,pattern 是要匹配的模式 fe:命名分組的寫法 下面是以URLconf 使用命名組的重寫: urls.py文件 from django.urls import path,re_path from app01 import views urlpatterns = [ re_path(r'^articles/2003/$', views.special_case_2003), re_path(r'^articles/(?P [0-9]{4})/$', views.year_archive), re_path(r'^articles/(?P [0-9]{4})/(?P [0-9]{2})/$', views.month_archive), re_path(r'^articles/(?P [0-9]{4})/(?P [0-9]{2})/(?P [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 會更加明晰且不容易產生參數順序問題的錯誤 —— 你能夠在你的視圖函數定義中從新安排參數的順序。固然,這些好處是以簡潔爲代價; PythonCopy 三、分發(目的:解耦合) 不是把全部的urls都寫在全局的urls.py文件中, 而是在全局的urls.py指向對應的app文件中的urls.py文件中, 在對應的app中作進一步的分發,從而達到了各個app的在全局的urls文件的解耦 # 全局的urls.py文件 urlpatterns = [ path('admin/', admin.site.urls), # 分發 url('app/', include('app.urls')), # 分發指向具體的app下,達到解耦 url('app02/', include('app02.urls')) ] # app01下的urls.py urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), # special_case_2003(request) ] # app02下的urls.py urlpatterns = [ url(r'^videos/(\d+)', views.videos), # special_case_2003(request) ] PythonCopy 四、反向解析 目的:動態的改變path路徑,從而避免硬編碼這些URL, 直白的說:改變原來的path,就要手動改把全部文件中有關於的這path的名字。 在使用Django 項目時,一個常見的需求是得到URL 的最終形式, 以用於嵌入到生成的內容中(視圖中和顯示給用戶的URL等)或者用於處理服務器端的導航(重定向等)。 一、在須要url的地方,咱們第一時間考慮url反查 在須要URL 的地方,對於不一樣層級,Django 提供不一樣的工具用於URL 反查: 一、在模板中:使用url 模板標籤。 二、在Python 代碼中:使用from django.urls import reverse()函數 兩種代碼及解釋示例 urls.py文件 from app01 import views urlpatterns = [ path('admin/', admin.site.urls), path('home/', views.index,name="index"), # 反向解析,動態的給view函數輸入path path('login.html/', views.login,name="Log"), # 反向解析,動態的給HTML的form表單,輸入重寫path ] views.py文件 from django.shortcuts import render,HttpResponse,redirect # Create your views here. from django.urls import reverse def login(request): _url=reverse("index") # 該命令是是動態的接收反向解析的path print("_url",_url) return redirect(_url) login.html文件
{# 這裏能夠動態的得到path路徑 #} {% csrf_token %} 用戶名 密碼
命名url: 不能夠跟其餘應用中的名稱衝突; 在URL 名稱中加上一個前綴,好比應用的名稱,將減小衝突的可能。 建議使用myapp-comment 而不是comment。 PythonCopy 3、MTV之視圖函數(Django的視圖層) 一個視圖函數,簡稱視圖,是一個簡單的Python 函數,它接受Web請求而且返回Web響應。 響應能夠是一張網頁的HTML內容,一個重定向,一個404錯誤,一個XML文檔, 或者一張圖片. . . 是任何東西均可以。 不管視圖自己包含什麼邏輯,都要返回響應。 代碼寫在哪裏也無所謂,只要它在你的Python目錄下面。 除此以外沒有更多的要求了——能夠說「沒有什麼神奇的地方」。 爲了將代碼放在某處,(全部的視圖函數約定放在這個文件下) 約定是將視圖放置在項目或應用程序目錄中的名爲views.py的文件中。 一、視圖函數的介紹 視圖層,熟練掌握兩個對象便可:請求對象(request)和響應對象(HttpResponse) 代碼介紹解釋 from django.shortcuts import render,HttpResponse,redirect # 響應體三劍客 # Create your views here. def index(request): # 響應體:HttpResponse render redirect # Django響應必定是HttpResponse類對象 #return HttpResponse("

INDEX

") good_list=['小米電視',"海爾冰箱","格力空調","AAA"] return render(request,"index.html",{"good_list":good_list}) 解釋: 一、首先,咱們從 django.shortcuts模塊導入了HttpResponse類,以及Python的datetime庫。 二、接着,咱們定義了current_datetime函數。它就是視圖函數。 每一個視圖函數都使用HttpRequest對象做爲第一個參數,而且一般稱之爲request。 注意,視圖函數的名稱並不重要;不須要用一個統一的命名方式來命名,以便讓Django識別它。 咱們將其命名爲current_datetime,是由於這個名稱可以精確地反映出它的功能。 三、這個視圖會返回一個HttpResponse對象,其中包含生成的響應。 每一個視圖函數都負責返回一個HttpResponse對象。 PythonCopy 二、HttpRequest對象 一、request屬性    django將請求報文中的請求行、首部信息、內容主體封裝成 HttpRequest 類中的屬性。 除了特殊說明的以外,其餘均爲只讀的。 request詳細解釋 1.HttpRequest.GET   一個相似於字典的對象,包含 HTTP GET 的全部參數。詳情請參考 QueryDict 對象。 2.HttpRequest.POST   一個相似於字典的對象,若是請求中包含表單數據,則將這些數據封裝成 QueryDict 對象。   POST 請求能夠帶有空的 POST 字典 —— 若是經過 HTTP POST 方法發送一個表單,可是表單中沒有任何的數據,QueryDict 對象依然會被建立。 所以,不該該使用 if request.POST 來檢查使用的是不是POST 方法;應該使用 if request.method == "POST"   另外:若是使用 POST 上傳文件的話,文件信息將包含在 FILES 屬性中。 注意:鍵值對的值是多個的時候,好比checkbox類型的input標籤,select標籤,須要用: request.POST.getlist("hobby") 3.HttpRequest.body   一個字符串,表明請求報文的主體。在處理非 HTTP 形式的報文時很是有用,例如:二進制圖片、XML,Json等。   可是,若是要處理表單數據的時候,推薦仍是使用 HttpRequest.POST 。 4.HttpRequest.path   一個字符串,表示請求的路徑組件(不含域名)。   例如:"/music/bands/the_beatles/" 5.HttpRequest.method   一個字符串,表示請求使用的HTTP 方法。必須使用大寫。   例如:"GET"、"POST" 6.HttpRequest.encoding   一個字符串,表示提交的數據的編碼方式(若是爲 None 則表示使用 DEFAULT_CHARSET 的設置,默認爲 'utf-8')。 這個屬性是可寫的,你能夠修改它來修改訪問表單數據使用的編碼。 接下來對屬性的任何訪問(例如從 GET 或 POST 中讀取數據)將使用新的 encoding 值。 若是你知道表單數據的編碼不是 DEFAULT_CHARSET ,則使用它。 7.HttpRequest.META   一個標準的Python 字典,包含全部的HTTP 首部。具體的頭部信息取決於客戶端和服務器,下面是一些示例: CONTENT_LENGTH —— 請求的正文的長度(是一個字符串)。 CONTENT_TYPE —— 請求的正文的MIME 類型。 HTTP_ACCEPT —— 響應可接收的Content-Type。 HTTP_ACCEPT_ENCODING —— 響應可接收的編碼。 HTTP_ACCEPT_LANGUAGE —— 響應可接收的語言。 HTTP_HOST —— 客服端發送的HTTP Host 頭部。 HTTP_REFERER —— Referring 頁面。 HTTP_USER_AGENT —— 客戶端的user-agent 字符串。 QUERY_STRING —— 單個字符串形式的查詢字符串(未解析過的形式)。 REMOTE_ADDR —— 客戶端的IP 地址。 REMOTE_HOST —— 客戶端的主機名。 REMOTE_USER —— 服務器認證後的用戶。 REQUEST_METHOD —— 一個字符串,例如"GET" 或"POST"。 SERVER_NAME —— 服務器的主機名。 SERVER_PORT —— 服務器的端口(是一個字符串)。   從上面能夠看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 以外,請求中的任何 HTTP 首部轉換爲 META 的鍵時, 都會將全部字母大寫並將鏈接符替換爲下劃線最後加上 HTTP_ 前綴。 因此,一個叫作 X-Bender 的頭部將轉換成 META 中的 HTTP_X_BENDER 鍵。 8.HttpRequest.FILES   一個相似於字典的對象,包含全部的上傳文件信息。 FILES 中的每一個鍵爲 中的name,值則爲對應的數據。   注意,FILES 只有在請求的方法爲POST 且提交的
帶有enctype="multipart/form-data" 的狀況下才會 包含數據。不然,FILES 將爲一個空的相似於字典的對象。 9.HttpRequest.COOKIES   一個標準的Python 字典,包含全部的cookie。鍵和值都爲字符串。 10.HttpRequest.session   一個既可讀又可寫的相似於字典的對象,表示當前的會話。只有當Django 啓用會話的支持時纔可用。 完整的細節參見會話的文檔。 11.HttpRequest.user(用戶認證組件下使用)   一個 AUTH_USER_MODEL 類型的對象,表示當前登陸的用戶。   若是用戶當前沒有登陸,user 將設置爲 django.contrib.auth.models.AnonymousUser 的一個實例。你能夠經過 is_authenticated() 區分它們。 例如: if request.user.is_authenticated(): # Do something for logged-in users. else: # Do something for anonymous users.   user 只有當Django 啓用 AuthenticationMiddleware 中間件時纔可用。 ------------------------------------------------------------------------------------- 匿名用戶 class models.AnonymousUser django.contrib.auth.models.AnonymousUser 類實現了django.contrib.auth.models.User 接口,但具備下面幾個不一樣點: id 永遠爲None。 username 永遠爲空字符串。 get_username() 永遠返回空字符串。 is_staff 和 is_superuser 永遠爲False。 is_active 永遠爲 False。 groups 和 user_permissions 永遠爲空。 is_anonymous() 返回True 而不是False。 is_authenticated() 返回False 而不是True。 set_password()、check_password()、save() 和delete() 引起 NotImplementedError。 New in Django 1.8: 新增 AnonymousUser.get_username() 以更好地模擬 django.contrib.auth.models.User。 PythonCopy 二、request經常使用方法 1.HttpRequest.get_full_path()   返回 path,若是能夠將加上查詢字符串。   例如:"/music/bands/the_beatles/?print=true" 2.HttpRequest.is_ajax()   若是請求是經過XMLHttpRequest 發起的,則返回True,方法是檢查 HTTP_X_REQUESTED_WITH 相應的首部是不是字符串'XMLHttpRequest'。   大部分現代的 JavaScript 庫都會發送這個頭部。若是你編寫本身的 XMLHttpRequest 調用(在瀏覽器端),你必須手工設置這個值來讓 is_ajax() 能夠工做。   若是一個響應須要根據請求是不是經過AJAX 發起的,而且你正在使用某種形式的緩存例如Django 的 cache middleware, 你應該使用 vary_on_headers('HTTP_X_REQUESTED_WITH') 裝飾你的視圖以讓響應可以正確地緩存。 PythonCopy 三、HttpResponse對象 響應對象主要有三種形式(響應三劍客): HttpResponse() render() redirect() HttpResponse()括號內直接跟一個具體的字符串做爲響應體, 比較直接很簡單,return HttpResponse("Error!") 因此這裏主要介紹後面兩種形式。 四、render()重點 render方法KEY: 1 找文件,讀文件 2 渲染數據 3 把最終渲染的字符串交給HttpResponse返回 寫法: render(request, template_name, [context]) 結合一個給定的模板和一個給定的上下文字典,並返回一個渲染後的 HttpResponse 對象。 views.py文件 def index(request): good_list=['小米電視',"海爾冰箱","格力空調","AAA"] # 這裏暫時模擬數據庫 return render(request,"index.html",{"good_list":good_list}) # 必須傳前面兩個參數,後面一個能夠不傳,這樣html裏{{}}就爲空,瀏覽器永遠看不到兩個大括號的, # 第三個參數,是字典的鍵值對,鍵爲HTML的{{ }}裏的字符串,值爲咱們讀取數據庫的數據 # render(三個參數的)執行過程解析: 一、首先去templates裏找HTML文件,找到了不是立刻返回HTML字符串,先識別有沒有{{ }}或者{% %} 二、找到了{{ }},將第三個參數的數據替換{{ }}(相似於寫入清空{{ }}),完成了渲染 三、將渲染後的html文件返回給瀏覽器 最終也是返回字符串,只不過他返回的是一個頁面字符串 index.html文件

This is Index!


商品列表html

{{ good_list }} // 這裏是render會識別去渲染他,{{ good_list}}是整個被替換 PythonCopy 五、redirect()重點 做用:重定向,(在原地址基礎上直接指定跳轉一個連接地址) 業務場景:登陸成功後,直接在登陸頁面跳轉本身的我的首頁 各個文件代碼示例 # urls.py文件 from django.contrib import admin from django.urls import path,re_path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), path('index/', views.index), # 我的首頁 path('login/', views.login), # 登陸認證,重定向到我的首頁, # 由於業務邏輯同樣,因此寫在一塊兒 ] PythonCopy views.py文件 from django.shortcuts import render,HttpResponse,redirect # 響應體三劍客 # Create your views here. def index(request): good_list=['小米電視',"海爾冰箱","格力空調","AAA"] # 模擬去數據庫取的數據 return render(request,"index.html",{"good_list":good_list}) def login(request): if request.method=="GET": # 經過請求方式,判斷獲取登陸頁面,仍是登陸驗證請求 return render(request,"login.html") else: #print(request.POST) # user = request.POST.get("user") # 獲取用戶輸入的用戶名 pwd = request.POST.get("pwd") print("user", user) if user == "alex" and pwd == "123": return redirect("/index/") # 這樣這裏寫死了代碼 return HttpResponse("Error!") # redict執行流程解析 一、執行到這裏,登陸驗證確定是成功的,這裏就要給用戶跳轉到我的首頁 # 這裏redirect會發送兩次響應給瀏覽器, 二、首先,redirect發一個沒有響應體的響應給瀏覽器,可是響應狀態碼爲301, 瀏覽器一讀取到這個狀態碼,就知道要馬上再發送一個請求給服務器, 才能拿到真正的響應體,這一步的操做,是瀏覽器作的,用戶並不知道的 (請求的路徑在響應頭裏的location,) 三、瀏覽器把真正的求路徑發過來,服務器接收到後,通過urls路由分發, 執行該路徑的視圖函數後,把相應的html頁面的字符串返回給瀏覽器, # redirct的優勢: 一、return redirect("/index/"),這裏他本身會去調用index視圖函數,實現了代碼複用 二、在咱們登陸成功後,若是卡了,那麼刷新,就不會再跑到還要登陸輸入的頁面, 由於此時的路徑已是你我的頁面的路徑了,實現了重定向 PythonCopy # login.py文件 用戶名 密碼 PythonCopy # index.py文件

This is Index!


商品列表ajax

{{ good_list }} PythonCopy 4、MTV之模板 一、渲染變量: {{}} 深度查詢 句點符,一直點就是一直往裏查找 過濾器 {{ val|filter_name:參數 }} 二、渲染標籤: {%%} {%for%} {%endfor%} 一、模板語法之變量(深度查詢) 在 Django 模板中遍歷複雜數據結構的關鍵是句點字符, 變量渲染過程: 一、views.py裏的視圖函數,拿到要傳遞給template文件的值(數據), 二、將變量經過render方法第三個參數以{"": }形式傳入給template模板文件; 三、template裏面用{{ "變量名" }},(變量名做爲上面參數的鍵,通常咱們鍵名=值名寫同樣的) 四、這樣render方法在加載template文件時就會識別{{ }},從而對變量進行渲染 五、渲染完成後再將整個template文件以字符串發送給瀏覽器。 view.py文件代碼示例 def index(request): s="alex" # 字符串 l=[111,222,333,444] # 列表 info={"name":"alex","age":34,"addr":"沙河"} # 字符串 class Animal(object): # 自定義類對象 def __init__(self,name,age): self.name=name self.age=age def paojiao(self): return 666 alex=Animal('alex',"45") egon=Animal('egon',"25") person_list=[alex,egon] return render(request,"index.html",{"s":s,"l":l,"info":info,"perso_list",person_list}) PythonCopy template的index.html文件變量示例

模板語法之變量

{{ name }}正則表達式

深度查詢:句點符 .數據庫

{{ l }}django

{{ l.0 }}瀏覽器

# 深度查詢

{{ info }}緩存

{{ info.name }}安全

{{ info.age }}服務器

{{ person_list }}cookie

{{ person_list.1.name }}

# 能夠一直往裏查詢,這就是深度

{{ person_list.1.paojiao }}

# 深度查詢,只能調用無參的方法 # 示例:注意:句點符也能夠用來引用對象的方法(無參數方法):

字典:{{ dic.name.upper }}

# 說白了就是括號也不能寫 HTMLCopy 二、模板之過濾器—-Django自帶的(格式化輸出數據) 語法: {{obj|filter__name:param} 做用:就是格式化輸出 解釋:就是能穿過過濾器的,都按同樣的格式輸出 一、一些自帶的過濾器 一些自帶的過濾器做用詳解 一、default 若是一個變量是false或者爲空,使用給定的默認值。不然,使用變量的值。例如: {{ value|default:"nothing" }} 二、length 返回值的長度。它對字符串和列表都起做用。例如: {{ value|length }} 若是 value 是 ['a', 'b', 'c', 'd'],那麼輸出是 4。 三、filesizeformat 將值格式化爲一個 「人類可讀的」 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如: {{ value|filesizeformat }} 若是 value 是 123456789,輸出將會是 117.7 MB。   四、date 若是 value=datetime.datetime.now() {{ value|date:"Y-m-d" }}    五、slice 若是 value="hello world" {{ value|slice:"2:-1" }} 六、truncatechars 若是字符串字符多於指定的字符數量,那麼會被截斷。 截斷的字符串將以可翻譯的省略號序列(「...」)結尾。 參數:要截斷的字符數 例如: {{ value|truncatechars:9 }} 八、truncatewords 截斷多少個詞

{{ shi|truncatewords:5 }}

# 要截斷的多少個詞, 七、safe Django的模板中會對HTML標籤和JS等語法標籤進行自動轉義,緣由顯而易見,這樣是爲了安全。 可是有的時候咱們可能不但願這些HTML元素被轉義,好比咱們作一個內容管理系統, 後臺添加的文章中是通過修飾的,這些修飾多是經過一個相似於FCKeditor編輯加註了HTML修飾符的文本, 若是自動轉義的話顯示的就是保護HTML標籤的源文件。 爲了在Django中關閉HTML的自動轉義有兩種方式, 若是是一個單獨的變量咱們能夠經過過濾器「|safe」的方式告訴Django這段代碼是安全的沒必要轉義。好比: value=" 點擊" {{ value|safe}} HTMLCopy 三、模板之標籤
相關文章
相關標籤/搜索