HTTPRequest與HTTPresponse 1、 1、互聯網兩臺機器之間通行:ip、端口、協議 - 協議 - HTTP (80) - HTTPS (443) 2、瀏覽器輸入URL一回車返回頁面發生了什麼? - 域名 -> DNS解析 -->ip地址 -> 找到服務端 ->服務端返回消息 -> 瀏覽器 - 瀏覽器 <-> 服務器 - 服務器把 寫好的HTML頁面,返回給瀏覽器,瀏覽器按照HTML格式渲染 「 」 3、請求和相應 - HTTP協議的特色: - 瀏覽器給服務端發消息的過程叫請求(request) - 服務器給瀏覽器回覆消息的過程叫響應(response) - 請求和相應的消息都必須遵循一個固定的格式 4、python中Web框架分類 - a、收發socket消息,按照HTTP協議解析消息 Web服務程序 wsgiref(模塊)、gunicorn、uWSGI - b、字符串替換,用來實現動態網頁 - c、業務邏輯處理 Web應用程序 1- 本身實現abc的 - Tronado 2- 本身實現bc使用別人的a - Django 3- 本身實現c使用別人的ab - Flask 五、Web服務程序 <- WSGI協議 -> Web應用程序 5.5、Django版本 - LTS版本 (Long Team support) 6、建立第一個Django項目 安裝: pip install django==1.11.11 pip install django==1.11.11 -i 指定源 - 一、命令行 Django-admin startproject first_Django - 2、Pycharm建立 - file -> new Project ->右側選Django -> 選好路徑 ->選好環境 -> 名字app -> 在新的窗口打開文件 - 3、啓動項目 - 命令行啓動(切換到項目的根目錄) - python manage.py runserver 127.0.0.1:8090(改端口這樣指定) - pycharm啓動 - 框中選項爲項目名->讓後點擊啓動按鈕(右上角)(若是想改就在旁邊點編輯-就能夠改端口等) - 目錄介紹 - 和項目名同樣的是根目錄 - --------------------- - 先來一份本身的理解 - 1、(與咱們所建立文件名一致的目錄)根目錄 - manage.py - 這是啓動文件,程序入口。 - settings.py - 包含了項目的一些設置,包括數據庫信息、調試標誌以及其餘的一些工做的變量。 - BASE_DIR = 項目的根目錄 - TIMELATES = templates去哪找 - DATABASES = 數據庫 - 靜態文件配置 - STATIC_URL = '/static/' # 請別名 - STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),] # 配置去static下找靜態文件 - urls.py - 路徑與視圖函數的映射關係 - 二、templates - 這個文件夾存放的是HTML文件 - 三、static - 這個文件夾是存放靜態文件,須要本身配置,用的時候的導入時用 /static/.. 來引入所用的靜態文件 # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ # 這個static就表明了下面的路徑 (尋找的時候就是去static下面的路徑中挨個找) STATIC_URL = '/static/' # 起別名, HTML中找靜態文件都要以這個別名開始 (找到別名後就去這個別名的配置比文件中找對應的文件) # 這個常量是固定格式 STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'), ] 7、項目流程 - 先輸入url - 去Django的urls中匹配urlpatterns->匹配上調用後面匹配的函數->去找對應的函數 - 找到執行的函數->Django調用要執行的函數給函數傳一個request參數,全部和請求相關的數據 都在request中 - render去templates文件夾找到HTML文件,打開讀取內容,按照http響應格式給瀏覽器返回讀取的內容 - 瀏覽器收到Django返回的響應消息,按照HTML格式顯示這個消息 其餘: - from django.shortcuts import HttpResponse, render - HttpResponse (封裝了協議頭等-有待商議) - render (渲染) - 文件的上傳(form表單的提交, 必須用POST) def index(request): print(request.GET) print(request.POST) print(request.FILES) for item in request.FILES: fileobj = request.FILES.get(item) f = open('upload/%s' % fileobj.name, 'wb') item_file = fileobj.chunks() for line in item_file: f.write(line) f.close() return HttpResponse("成功") - form表單上傳文件時須要注意的事情 - action 最後加 / 或者 修改settings:APPEND_SLASH=False - method 必須爲post - enctype = 「multipart/form-data」 必須寫 - 指定IP登陸 默認IP和端口 python manage.py runserver 指定端口: python manage.py runserver 192.168.12.12:8080 此時會報錯,咱們須要修改配置文件: 修改settings.py,將192.168.12.12添加到ALLOWED_HOSTS中 ALLOWED_HOSTS=['172.31.169.182','127.0.0.1','192.168.1.50','192.168.1.115'] 也能夠將ALLOWED_HOSTS改爲通配符 * ALLOWED_HOSTS = ["*"] 2、 1、表單的提交(登陸) - submit -> action -> 對應函數(參數request(數據信息))-> 處理 注意:必需要有name屬性 ***** - 提交到服務器的是QueryDict對象,能夠經過get獲取值 2、form表單提交的三個要素 - form標籤必須有action和method屬性 - 全部獲取用戶輸入的標籤必須放在form表單中,必須有name屬性(input,select,textarea) - 必須有submit按鈕 3、redirect 跳轉,改變方向 - 跳轉到別人的頁面,本身的頁面 - 跳轉比人頁面 redirect("https://baidu.com") - 跳轉本身頁面 redirect("/相對路徑/") 四、Django必會三件套 from django.shortcuts import - HttpRequest 返回一個指定的字符串 (把字符串轉爲而二進制,而後按照HTTP響應格式要求返回) - render 返回一個HTML文件 HTML文件 模板語言 (第一個參數爲request, 第二個參數爲render的頁面,第三個參數爲字典,將render頁面中的特殊符號替換{字典的鍵爲html的變量,值爲給頁面展現的值}) - redirect 跳轉 路徑 URL (redirect(/index/) -> 在同網站不一樣地址間跳轉(返回重定向響應) redirect('https://wwww.baidu.com') -> 訪問指定的網址) 5、request相關屬性 (全部和請求相關的數據都封裝在request對象中) - POST 取到POST提交的數據(form表單提交的) - GET 取到URL攜帶的參數 - method 當前此次請求的方法(GET/POST) 6、Django的模板語言 {{ 變量 }} 7、Django項目project - app(應用) -> 不一樣的功能放在不一樣的app中 - 命令 : - 建立app python manage.py startapp app01(應用名) - 註冊app(告訴Django建立了app) 在settings中的 INSTALLED_APPS 添加新建立的app(app名.apps.apps中的類) 8、程序連接mysql - 使用pymysql模塊 - 導入pymysql - 建立連接 - 獲取執行命令的遊標 - 用遊標執行SQL語句 - 獲取SQL語句的執行結果 - 關閉遊標 - 關閉連接 - ORM - Object Relationship Mapping (對象關係映射) - 這時,建立一種工具 幫助咱們翻譯SQL語句(ORM - 面向對象的思想) - 優勢 - 開發效率高 - 開發不用直接寫SQL語句 - 缺點 - 執行效率低 - 對應關係 ORM DB 類 數據表 屬性 字段 對象 數據行 - Django項目project - app(應用) -> 不一樣的功能放在不一樣的app中 - 命令 : - 建立app python manage.py startapp app01(應用名) - 告訴Django建立了app 在settings中的 INSTALLED_APPS 添加新建立的app(app名.apps.apps中的類) - Django中ORM使用 - 用處: - 操做數據表 - 操做數據行 - 使用 - 手動建立數據庫 - 告訴Django連那個數據庫 - settings中配置DATABASES DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 連接數據庫的類型 'NAME': 'db', # 連接數據庫的名字 'HOST': '127.0.0.1', # 數據庫主機地址 'PORT': 3306, # 數據庫端口 'USER': 'root', # 數據庫用戶名 'PASSWORD': '123456', # 數據庫密碼 } } - 用什麼連接數據庫? - 利用第三方包 pymysql 和 MySQLdb(py2中) - 告訴Django用pymysql模塊代替默認的MySQLdb連接MySQL數據庫 和settings.py同級的__init__.py文件,寫上 import pymysql pymysql.install_as_MySQLdb() - 在app/models.py的文件中建立類 類必須繼承models.Model - 兩個命令 - python manage.py makemigrations -> 生成腳本文件存放在app文件夾應用下的migrations文件夾中(至關於拿個小本本把models.py的變動記錄下來) - python manage.py migrate -> 把上面的變動記錄翻譯成sql語句,去數據庫執行 - ORM查詢 modules.User.object.filter(email='', pwd='') 3、 1、圖書管理系統 - 出版社 id name - 做者 id name - 書 id title 出版社_id - 書_做者關係表 id 書_id 做者_id 2.ORM增刪改查 models.表名.object./filter()/all()/create() - filter() 按照指定內容篩選 (字段=值) 放回一個列表 - all() 查詢出數據庫全部信息(屬性order_by(id)排序) 返回一個列表 - create() 向數據庫添加信息 (字段=值)建立一個對象 返回一個建立的對象 - get() 返回一個對象 - filter(id='').delete() 刪除 - obj = 類名.object.get(id='') obj.name = '新值' 修改對象的屬性(修改數據行某個字段的值) obj.save() 把修改同步到數據庫 3、模板語言 - for循環 {% for i in ret %} {{ i }} {{ forloop.counter }} for循環從1開始計數 {{ forloop.counter0 }} for循環從0開始計數 {% endfor %} 總結:ORM的 查、增、刪、改 - 查 - client - 有一個展現頁面(xxx_show.html) - 這一個頁面一輸入執行後,get請求向server端發送 - 這個展現頁面有添加按鈕、刪除按鈕、編輯按鈕 - 這個頁面要展現內容 - 是server端收到第一次的get請求而作出的response - 頁面須要用到模板語言for循環 {% for i in result %} {{ i.xx }} #獲取result中的每一個值(也就是server端傳來的東西) {% endfor %} - server - 首先會收到一開始訪問頁面的GET請求 - 收到請求後到urls中找匹配的url,找到對應的url後,執行後面所對應的視圖函數 - 找到對應的視圖函數後就行執行響應的邏輯,也就是拿出數據庫中的東西,發送給server - 能夠經過 models.表名.objects.all() 獲取數據庫這張表中的全部內容(返回一個列表) - data = models.表名.objects.all() - 拿到數據後將這些數據給展現(經過render方法) - return render(request, 'xxx_show.html', 'result':data) #這裏的result就是要傳給xxx_show.html的一個變量(其中的值就是data的數據) - 增 - client - 有一個展現頁面(xxx_show.html) - 這個頁面有一個添加按鈕(a標籤) - 點擊這個按鈕(a標籤),client會發送一個get請求,會用a標籤的路徑去訪問server - 這時會跳轉到a標籤所指的url(/add_xxx/) - 而後server給出response(這裏的業務邏輯就都得在server) - 第一次get請求server會返回一個add_xxx.html頁面 - 這是能夠添加數據 - 用form表單,action爲add_xxx這個url,method爲post - 點擊提交以後client向server發送一個請求 - server收到請求後回覆一個response - server - 收到a標籤跳轉的url(get請求響應) - 收到add_xxx這個url進入urls中匹配,匹配到就去他對應的視圖函數 - 這個視圖函數處理響應的業務邏輯 - 首先第一次來的時候時GET請求,這個時候應該將add_xxx.html這個頁面返回給client - return render(request, add_xxx.html) - 而後server收到提交的POST請求 - 從POST請求中拿出client發送來的數據 - data = request.POST.get("input標籤的name") - 將數據存入數據庫 - models.tablename.objects.create(字段=data) - 將數據庫中的結果從新返回(也就是xxx_show。html) - return redirect('/xxx_show/') - 刪 - client - 有一個展現頁面(xxx_show.html) - 有一個刪除按鈕(a標籤) - 點擊這個按鈕(a標籤),client會發送一個get請求,會用a標籤的路徑去訪問server - 點擊這個a標籤(按鈕)會跳轉到他對應的url('/del_xxx/') - 這時須要將這個按鈕對應的數據傳到server,server才能按照這個數據去刪除 - <a href="/del_xxx/?id={{ i.id }}"><button>del</button></a> - ?是一個固定格式,然後面就是一些參數(服務端要用的一些參數) - server收到這個參數後就能夠按照他進行相應的操做 - 而後server會返回一個response(這裏的業務邏輯在server端) - server - 收到a標籤跳轉的url(get請求響應) - 收到del_xxx這個url進入urls中匹配,匹配到就去他對應的視圖函數 - 這個視圖函數處理響應的業務邏輯 - 經過client傳來的參數來鎖定刪除的id - del_id = request.GET.get("id") - 刪除數據庫中del_id對應的值 - models.tablename.objects.fileter(id=del_id).delete() - 刪除成功後返回刪除後的頁面('/xxx_show/')(重定性) - return redirect('/xxx_show/') - 改 - client - 有一個展現頁面(xxx_show.html) - 有一個編輯(edit)按鈕(a標籤) - 點擊這個按鈕(a標籤),client會發送一個get請求,會用a標籤的路徑去訪問server - 點擊這個a標籤(按鈕)會跳轉到他對應的url('/edit_xxx/') - 這時須要將這個按鈕對應的數據傳到server,server才能更改這個數據 - <a href="/edit_xxx/?id={{ i.id }}"><button>del</button></a> - ?是一個固定格式,然後面就是一些參數(服務端要用的一些參數) - server收到這個參數後就能夠按照他進行相應的操做 - 而後server會返回一個response(這裏的業務邏輯在server端) - 第一次發送get請求時會跳轉到edit_xxx.html這個頁面,這裏面是該行對應的數據 - 第二次發送post請求,這裏面會有修改後的數據而後發送給server處理 - <form action="/edit_press/?id={{ result.id }}" method="post"> <input type="text" name="updata_name" value="{{ result.name }}"> <input type="submit"> </form> - input中的數據都是在server查出的數據展示出來的 - id是經過點擊edit按鈕的時候將這個按鈕對應的id值記錄了下來 - 處理完後返回原來的xxx_show - server - 收到a標籤跳轉的url(get請求響應) - 收到edit_xxx這個url進入urls中匹配,匹配到就去他對應的視圖函數 - 這個視圖函數處理響應的業務邏輯 - 第一遍的GET請求 - 經過client傳來的參數來鎖定編輯(edit)的id - edit_id = request.GET.get("id") - 會返回當前編輯行的內容 - 從數據庫中拿出這個值,將這個值展示在edit_xxx.html頁面中 - result = models.tablename.objects.filter(id="")[0] - 返回當前編輯的頁面 - return render(request, 'edit_xxx.html', {'resule': result}) - 第二遍請求是提交數據後的POST請求, - form表單中的action爲這個編輯頁面, - 這個頁面後面的參數爲第一次get請求獲得的數據 - 能夠經過GET方法來獲取URL上的參數的值 - 這個時候form表單對應的url來urls中找對應的視圖函數 - 這個視圖函數就會執行POST請求的邏輯 - 用這個新數據把數據庫中的舊數據掩蓋 - 獲取更改後的值 - data = request.POST.get("updata_name") - 更改數據庫中的值 - 從數據庫找到id對應的對象 - #這裏的id就是第一次點擊編輯的時候獲得的id值(--對應的) - new_obj = models.tablename.objects.filter(id='edit_id')[0] - new_obj.name = data #將新的值賦值給數據庫中的變量 - new_obj.save() #這個事務必須save數據庫中的數據纔會更改 - 更改完成後返回,xxx_show頁面 - return redirect('/xxx_show/') 注意: 經過GET來獲取URL中的值(和請求無關),POST獲取表單提交的值。 4、 1、 a標籤 - href屬性 - 相對路徑 - 絕對路徑 - target = "_blank" 跳轉到新頁面, 不寫默認覆蓋本身的頁面 - 錨點(同網站標籤的跳轉(#id名)) 2、 # 出版社 class Press(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) def __str__(self): # print的時候測試使用 return self.name # 書 class Book(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(max_length=32) # Django1.1默認就是級聯刪除,2.0必須指定 # 能夠經過字符串的反射找Press,若是在代碼前面就能夠直接用,to=關聯的表名 # 外鍵字段ORM會給他默認加一個_id (加上_id後他的值就是對應關聯表的主鍵值) press = models.ForeignKey(to='Press', on_delete=models.CASCADE) - 一對多 - 一個出版社對應多本書(外鍵設置在多的一方) - 書的屬性有一個外鍵爲連接出版社的press_id 書籍的增刪改查 - 增 - 刪 - 改 - 查 注意: - 增的時候,出版社就是表中的固定出版社,用一個select標籤將數據展現,而不是用戶本身填 <form action="/add_book/" method="post"> 書名:<input type="text" name="book_title"> <select name="title_name" id=""> {% for press in data %} <option value="{{ press.id }}"> {{ press.name }} </option> {% endfor %} </select> <input type="submit"> </form> - 改的實時,出版社的內容須要先選定好。須要用模板語言來判斷 # 這中狀況form表單不指定action他默認會提交當前的頁面(這是的頁面是點擊編輯時的頁面) <form action="/edit_book/?id={{ data.id }}" method="post"> <input type="text" name="title_name" value="{{ data.title }}"> <select name="press_name" id=""> {% for press in data_list %} {% if data.press == press %} <option value="{{ press.id }}" selected> </option> {{ press.name }} {% else %} <option value="{{ press.id }}"> {{ press.name }} </option> {% endif %} {% endfor %} </select> <input type="submit"> </form> 5、 - 給數據庫中已經存在的表添加另一個字段,ORM不知道如何處理 - 1) 輸入 1 會讓用戶本身填寫一個默認值(在命令行中) - 2) 輸入 2 本身在ORMclass中指定字段本身加默認值(退出命令行)在modules中修改 - null = True - default = 默認值 1. 多對多關係 做者 <--> 書籍 1. 表結構設計 1. SQL版 -- 建立做者表 create table author( id int primary key auto_increment, name varchar(32) not null ); -- 建立做者和書的關係表 create table author2book( id int primary key auto_increment, author_id int not null, book_id int not null, constraint fk_author foreign key (author_id) references author(id) on delete cascade on update cascade, constraint fk_book foreign key (book_id) references book(id) on delete cascade on update cascade ); 2. ORM版 1. 初版: 本身建立第三張表 2. 第二版 讓ORM幫咱們建立第三張表 models.ManyToManyField() 3. 第三版 待補充...(ORM進階操做的時候) 2. 做者的增刪改查 1. 查詢 author_obj.books --> 獲得的只是一個關聯關係,並不能拿到數據 author_obj.books.all() --> 獲得和我這個做者關聯的全部書籍對象列表 2. 添加 1. getlist() # 獲得同一name的列表對象 2. add() 3. set() 3. 刪除 4. 編輯 1. 模板語言中 {% if book in author.books.all %} 2. ORM編輯多對多 1. 不能直接操做第三張關係表 2. 藉助ORM給提供的方法 1. all() 2. add(id1,id2) 3. set([id1, id2]) 4. clear() 3. Django模板語言 1. for循環 1. forloop.last {% if forloop.last %} ... 2. empty {% for i in x %} ... {% empty %} ... {% endfor %} 4. 上傳文件 form表單上傳文件 # 文件的上傳 def index(request): print(request.FILES) # 上傳的文件列表對象 for item in request.FILES: fileobj = request.FILES.get(item) # 挨個獲取列表中每一個對象 f = open('upload/%s' % fileobj.name, 'wb') item_file = fileobj.chunks() for line in item_file: f.write(line) f.close() return HttpResponse("成功") 2. 學生管理系統 - 老師 和 班級 是多對多的關係 6、Django模板系統(模板語言)(very important) - 基礎語法 - 跟變量相關 {{ }} 在Django的模板語言中按此語法使用:{{ 變量名 }}。 當模版引擎遇到一個變量,它將計算這個變量,而後用結果替換掉它自己。 變量的命名包括任何字母數字以及下劃線 ("_")的組合。 變量名稱中不能有空格或標點符號。 點(.)在模板語言中有特殊的含義。當模版系統遇到點("."),它將以這樣的順序查詢: ***** 屬性->方法->索引 字典查詢(Dictionary lookup) 屬性或方法查詢(Attribute or method lookup) 數字索引查詢(Numeric index lookup) 注意事項: 若是計算結果的值是可調用的,它將被無參數的調用。 調用的結果將成爲模版的值。 若是使用的變量不存在, 模版系統將插入 string_if_invalid 選項的值, 它被默認設置爲'' (空字符串) 。 {# 取l中的第一個參數 #} {{ l.0 }} {# 取字典中key的值 #} {{ d.name }} {# 取對象的name屬性 #} {{ person_list.0.name }} {# .操做只能調用不帶參數的方法 #} {{ person_list.0.dream }} - Filter過濾器 在Django的模板語言中,經過使用 過濾器 來改變變量的顯示。 過濾器的語法: {{ value|filter_name:參數 }} 使用管道符"|"來應用過濾器。 例如:{{ name|lower }}會將name變量應用lower過濾器以後再顯示它的值。lower在這裏的做用是將文本全都變成小寫。 注意事項: 過濾器支持「鏈式」操做。即一個過濾器的輸出做爲另外一個過濾器的輸入。 過濾器能夠接受參數,例如:{{ sss|truncatewords:30 }},這將顯示sss的前30個詞。 過濾器參數包含空格的話,必須用引號包裹起來。好比使用逗號和空格去鏈接一個列表中的元素,如:{{ list|join:', ' }} '|'左右 沒有空格沒有空格沒有空格 ****** Django的模板語言中提供了大約六十個內置過濾器 - 一些經常使用的過濾器 - default 若是一個變量是false或者爲空,使用給定的默認值。 不然,使用變量的值。 {{ value|default:"nothing"}} 若是value沒有傳值或者值爲空的話就顯示nothing 注:TEMPLATES的OPTIONS能夠增長一個選項:string_if_invalid:'找不到',能夠替代default的的做用。 - length 返回值的長度,做用於字符串和列表。 {{ value|length }} 返回value的長度,如 value=['a', 'b', 'c', 'd']的話,就顯示4. - filesizeformat 將值格式化爲一個 「人類可讀的」 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如: {{ value|filesizeformat }} 若是 value 是 1234567890,輸出將會是 1.1GB。 - slice 切片 {{value|slice:"2:-1"}} - add 給變量加參數 {{ value|add:"2" }} value是數字4,則輸出結果爲6。 {{ first|add:second }} 若是first是 [1,.2,3] ,second是 [4,5,6] ,那輸出結果是 [1,2,3,4,5,6] 。 - data 格式化 {{ value|date:"Y-m-d H:i:s"}} 可用的參數: 格式化字符 描述 示例輸出 a 'a.m.'或'p.m.'(請注意,這與PHP的輸出略有不一樣,由於這包括符合Associated Press風格的期間) 'a.m.' A 'AM'或'PM'。 'AM' b 月,文字,3個字母,小寫。 'jan' B 未實現。 c ISO 8601格式。 (注意:與其餘格式化程序不一樣,例如「Z」,「O」或「r」,若是值爲naive datetime,則「c」格式化程序不會添加時區偏移量(請參閱datetime.tzinfo) 。 2008-01-02T10:30:00.000123+02:00或2008-01-02T10:30:00.000123若是datetime是天真的 d 月的日子,帶前導零的2位數字。 '01'到'31' D 一週中的文字,3個字母。 「星期五」 e 時區名稱 多是任何格式,或者可能返回一個空字符串,具體取決於datetime。 ''、'GMT'、'-500'、'US/Eastern'等 E 月份,特定地區的替表明示一般用於長日期表示。 'listopada'(對於波蘭語區域,而不是'Listopad') f 時間,在12小時的小時和分鐘內,若是它們爲零,則分鐘停留。 專有擴展。 '1','1:30' F 月,文,長。 '一月' g 小時,12小時格式,無前導零。 '1'到'12' G 小時,24小時格式,無前導零。 '0'到'23' h 小時,12小時格式。 '01'到'12' H 小時,24小時格式。 '00'到'23' i 分鐘。 '00'到'59' I 夏令時間,不管是否生效。 '1'或'0' j 沒有前導零的月份的日子。 '1'到'31' l 星期幾,文字長。 '星期五' L 布爾值是不是一個閏年。 True或False m 月,2位數字帶前導零。 '01'到'12' M 月,文字,3個字母。 「揚」 n 月無前導零。 '1'到'12' N 美聯社風格的月份縮寫。 專有擴展。 'Jan.','Feb.','March','May' o ISO-8601周編號,對應於使用閏年的ISO-8601週數(W)。 對於更常見的年份格式,請參見Y。 '1999年' O 與格林威治時間的差別在幾小時內。 '+0200' P 時間爲12小時,分鐘和'a.m。'/'p.m。',若是爲零,分鐘停留,特殊狀況下的字符串「午夜」和「中午」。 專有擴展。 '1 am','1:30 pm' / t3>,'midnight','noon','12:30 pm' / T10> r RFC 5322格式化日期。 'Thu, 21 Dec 2000 16:01:07 +0200' s 秒,帶前導零的2位數字。 '00'到'59' S 一個月的英文序數後綴,2個字符。 'st','nd','rd'或'th' t 給定月份的天數。 28 to 31 T 本機的時區。 'EST','MDT' u 微秒。 000000 to 999999 U 自Unix Epoch以來的二分之一(1970年1月1日00:00:00 UTC)。 w 星期幾,數字無前導零。 '0'(星期日)至'6'(星期六) W ISO-8601週數,週數從星期一開始。 1,53 y 年份,2位數字。 '99' Y 年,4位數。 '1999年' z 一年中的日子 0到365 Z 時區偏移量,單位爲秒。 UTC以西時區的偏移量老是爲負數,對於UTC以東時,它們老是爲正。 -43200到43200 - safe Django的模板中會對HTML標籤和JS等語法標籤進行自動轉義,緣由顯而易見,這樣是爲了安全。 可是有的時候咱們可能不但願這些HTML元素被轉義,好比咱們作一個內容管理系統,後臺添加的 文章中是通過修飾的,這些修飾多是經過一個相似於FCKeditor編輯加註了HTML修飾符的文本, 若是自動轉義的話顯示的就是保護HTML標籤的源文件。爲了在Django中關閉HTML的自動轉義有 兩種方式,若是是一個單獨的變量咱們能夠經過過濾器「|safe」的方式告訴Django這段代碼是安 全的沒必要轉義。 好比: value = "<a href='#'>點我</a>" {{ value|safe}} - truncchars 若是字符串字符多於指定的字符數量,那麼會被截斷。截斷的字符串將以可翻譯的省略號序列(「...」)結尾。 參數:截斷的字符數 {{ value|truncatechars:9}} - truncatewords 在必定數量的字後截斷字符串。 {{ value|truncatewords:9}} - cut 移除value中全部的與給出的變量相同的字符串 {{ value|cut:' ' }} 若是value爲'i love you',那麼將輸出'iloveyou'. - join 使用字符串鏈接列表,例如Python的str.join(list) - timesince 將日期格式設爲自該日期起的時間(例如,「4天,6小時」)。 採用一個可選參數,它是一個包含用做比較點的日期的變量(不帶參數,比較點爲如今)。 例如,若是blog_date是表示2006年6月1日午夜的日期實例,而且comment_date是2006年6月1日08:00的日期實例,則如下將返回「8小時」: {{ blog_date|timesince:comment_date }} 分鐘是所使用的最小單位,對於相對於比較點的將來的任何日期,將返回「0分鐘」。 - timeuntil 似於timesince,除了它測量從如今開始直到給定日期或日期時間的時間。 例如,若是今天是2006年6月1日,而conference_date是保留2006年6月29日的日期實例,則{{ conference_date | timeuntil }}將返回「4周」。 使用可選參數,它是一個包含用做比較點的日期(而不是如今)的變量。 若是from_date包含2006年6月22日,則如下內容將返回「1周」: {{ conference_date|timeuntil:from_date }} - 自定義filter - 自定義過濾器只是帶有一個或兩個參數的Python函數: 變量(輸入)的值 - -不必定是一個字符串 參數的值 - 這能夠有一個默認值,或徹底省略 例如,在過濾器{{var | foo:'bar'}}中,過濾器foo將傳遞變量var和參數「bar」。 - 建立 (步驟) - 先在app目錄下建立一個templatetagspython包(名字必須這個) - 在目錄中建立一個py文件 - 在py文件中按照固定的格式自定義一個filter(就是一個函數) - 須要先導入 from django import template # 固定寫法,生成一個註冊實例對象 register = template.Library() @register.filter() # 告訴Django的模板語言我如今註冊一個自定義的filter def add_str():pass # 第一個參數是變量名, 第二個參數爲參數(最多一個) - 使用: - 重啓DJango項目 - 在HTML頁面中:{% load python文件名 %} - {{ name|add_str:'好人啊' }} - 例子: - 自定義過濾器只是帶有一個或兩個參數的Python函數: 變量(輸入)的值 - -不必定是一個字符串 參數的值 - 這能夠有一個默認值,或徹底省略 例如,在過濾器{{var | foo:「bar」}}中,過濾器foo將傳遞變量var和參數「bar」。 - 自定義filter代碼文件擺放位置: app01/ __init__.py models.py templatetags/ # 在app01下面新建一個package package __init__.py app01_filters.py # 建一個存放自定義filter的py文件 views.py - 編寫自定義filter from django import template register = template.Library() @register.filter def fill(value, arg): return value.replace(" ", arg) @register.filter(name="addSB") def add_sb(value): return "{} SB".format(value) - 使用自定義filter {# 先導入咱們自定義filter那個文件 #} {% load app01_filters %} {# 使用咱們自定義的filter #} {{ somevariable|fill:"__" }} {{ d.name|addSB }} - 注意:過濾器能夠連接 {{ text|escape|linebreaks }} 就是一個經常使用的過濾器鏈,它編碼文本內容,而後把行打破轉成<p> 標籤。 - 跟邏輯相關 {% %} - 語法爲:{% tag %} - for <ul> {% for user in user_list %} <li>{{ user.name }}</li> {% endfor %} </ul> for循環可用的一些參數: Variable Description forloop.counter 當前循環的索引值(從1開始) forloop.counter0 當前循環的索引值(從0開始) forloop.revcounter 當前循環的倒序索引值(從1開始) forloop.revcounter0 當前循環的倒序索引值(從0開始) forloop.first 當前循環是否是第一次循環(布爾值) forloop.last 當前循環是否是最後一次循環(布爾值) forloop.parentloop 本層循環的外層循環(是個字典) forloop是一個字典 - for ... empty <ul> {% for user in user_list %} <li>{{ user.name }}</li> {% empty %} <li>空空如也</li> {% endfor %} </ul> - if,elif和else {% if user_list %} 用戶人數:{{ user_list|length }} {% elif black_list %} 黑名單數:{{ black_list|length }} {% else %} 沒有用戶 {% endif %} 固然也能夠只有if和else {% if user_list|length > 5 %} 七座豪華SUV {% else %} 黃包車 {% endif %} 注: - if語句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判斷。 - with (就至關於起了一個別名) - {% with p1.dream as dream %} {{ dream }} # dream 代替p1.dream {% endwith %} - 定義一箇中間變量 {% with total=business.employees.count %} {{ total }} employee{{ total|pluralize }} {% endwith %} - csrf_token - 這個標籤用於跨站請求僞造保護。 - 在頁面的form表單裏面寫上{% csrf_token %} - 用這個後就能夠將中間件打開(這樣就安全了,知道是我可以收取的) - 在表單中添加了一個隱藏的input標籤 - name csrfmiddlewaretoken - value asksdasdas(64位) - # 註釋 - {# ... #} - 母版(一個普通的html文件) block extends - 減小代碼的重複 - 母版寫好 - 不一樣的地方用如下佔位 - {{ block contenter(name) }} {{ endblock }} - 子文件 - {% extends '母版html' %} # 繼承母版 - {% block contenter(name) %} # 將母版中的站好位置額contenter填充 本身的html文件 {% endblock %} - 注意事項: - {% extends '母版html' %} # 繼承母版 必須寫在開頭 - {% extends name %} name寫繼承的模板的名字字符串 - 自定義的內容寫在block中 - 定義多個block塊,通常要有js css - 注意事項 - Django的模板語言不支持連續判斷,即不支持如下寫法: {% if a > b > c %} ... {% endif %} - Dja的模板語言中屬性的優先級大於方法 def xx(request): d = {"a": 1, "b": 2, "c": 3, "items": "100"} return render(request, "xx.html", {"data": d}) 如上咱們在使用render方法渲染一個頁面的時候,傳的字典d有一個key是items而且還有默認的 d.items() 方法,此時在模板語言中: {{ data.items }} 默認會取d的items key的值。 - 組件 include - 能夠將經常使用的頁面內容如導航條,頁尾信息等組件保存在單獨的文件中,而後在須要使用的地方按以下語法導入便可。 {% include 'navbar.html' %} - 靜態文件相關(動態拿取STATIC_URL配置的名字) - {% load static %} <img src="{% static "images/hi.jpg" %}" alt="Hi!" /> 引用JS文件時使用: {% load static %} <script src="{% static "mytest.js" %}"></script> 某個文件多處被用到能夠存爲一個變量 {% load static %} {% static "images/hi.jpg" as myphoto %} <img src="{{ myphoto }}"></img> - get_static_prefix {% load static %} <img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" /> 或者 {% load static %} {% get_static_prefix as STATIC_PREFIX %} <img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" /> <img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" /> - 自定義simpletag 和自定義filter相似,只不過接收更靈活的參數。 定義註冊simple tag @register.simple_tag @register.simple_tag(name="plus") def plus(a, b, c): return "{} + {} + {}".format(a, b, c) 使用自定義simple tag {% load app01_demo %} {# simple tag #} {% plus "1" "2" "abc" %} - inclusion_tag - 多用於返回html代碼片斷 - 步驟 - 在app下建立templatetags的python包 - 在包下寫py文件 mytags - 編輯文件 - from django import template - register = template.Library() - 定義函數 - 可接受參數 - 返回一個字典 - 函數加裝飾器 - @register.inclusion_tag('result.html') 示例: templatetags/my_inclusion.py from django import template register = template.Library() @register.inclusion_tag('result.html') def show_results(n): n = 1 if n < 1 else int(n) data = ["第{}項".format(i) for i in range(1, n+1)] return {"data": data} templates/result.html <ul> {% for choice in data %} <li>{{ choice }}</li> {% endfor %} </ul> templates/index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>inclusion_tag test</title> </head> <body> {% load my_inclusion %} {% show_results 10 %} </body> </html> - 細節 input data屬性 value='是一個「-」連接的字符串'