day18 2018-08-19 1. 講課內容: 1. session:https://www.cnblogs.com/liwenzhou/p/8343243.html 1. Cookie是保存在瀏覽器端的鍵值對 用來解決HTTP請求是無狀態的 2. Django裏面使用Cookie 1. 設置Cookie 1. 回覆響應時設置的 rep = HttpResponse("OK") rep.set_cookie("key", "value", max_age=超時時間(秒)) rep.set_signed_cookie("key", "value", salt="鹽", max_age=超時時間(秒)) 2. 獲取Cookie 請求來的時候從請求中找cookie 1. request.COOKIES.get("key") 2. request.get_signed_cookie("key", default="", salt="鹽") 3. 爲何要有session 1. Cookied額缺點: 1. 數據量只有4096 2. 數據都保存在客戶端(瀏覽器)上,不安全 2. Session 保存在服務端的鍵值對 1. 請求來了以後,仍是生成隨機字符串 2. 以隨機字符串爲key,在服務端生成一個大字典,真正保存數據是value 3. 把隨機字符串以cookie的形式回覆給瀏覽器 4. 下一次請求再來的時候,會攜帶上一步的隨機字符串 5. 從請求中拿到隨機字符串, 6. 去後端以 該隨機字符串爲key找對應的value 7. value裏面存的就是真正有用的數據 3. Django中如何使用Session 1. 不管設置Session仍是獲取Session都是針對request對象來操做 2. 設置Session request.session["key"] = "value" 3. 獲取session request.session.get("key") 4. 其餘經常使用命令 1. # 將全部Session失效日期小於當前日期的數據刪除 request.session.clear_expired() 2. # 刪除當前的會話數據並刪除會話的Cookie。 request.session.flush() 3. 設置超時時間 request.session.set_expiry(7) 5. 經常使用配置項(寫在Settings.py中) # 全局配置session超時時間 SESSION_COOKIE_AGE = 60 * 60 * 24 * 2 # 是否每次請求都刷新session超時時間 SESSION_SAVE_EVERY_REQUEST = True 2. 分頁:https://www.cnblogs.com/liwenzhou/p/8343243.html最下面 1. 如何在單獨的一個腳本文件中使用Django的一些變量或方法 2. bulk_create() Django ORM批量建立的一個方法 分頁: 每頁顯示10條 1 0-10 2 10-20 3 20-30 n (n-1)*10-n*10 3. 中間件:https://www.cnblogs.com/liwenzhou/p/8761803.html 1. 何時使用中間件? 當須要在全局改變Django框架的輸入輸出時 2. 中間件不宜添加過多,功能過於複雜 不然會增長請求的響應時間 3. Django如何使用 1. 五個方法(三個經常使用) 主要記憶:執行時間、執行順序、參數和返回值 1. process_request(self,request) 1. 執行時間 在執行視圖函數以前執行 2. 執行順序 按照註冊的順序執行 3. 參數和返回值 1. request參數和視圖函數中是同一個對象 2. 返回值: 1. 返回None:請求繼續日後執行 2. 返回響應對象:請求就結束了,要返回響應了 2. process_response(self, request, response) 1. 執行時間 視圖函數執行以後(拿到響應對象以後) 2. 執行順序 按照註冊的倒序執行 3. 參數和返回值 1. 參數:request請求對象 response:響應對象 2. 返回值: 只能返回響應對象 1. 返回默認的 2. 本身生成一個響應對象返回 3. process_view(self, request, view_func, view_args, view_kwargs) 1. 執行時間 視圖函數以前,在urls.py找到將要執行的視圖函數以後 2. 執行順序 註冊的順序執行 3. 參數和返回值 1. 參數: 1. request: 請求對象 2. view_func:將要執行的視圖函數 2. 返回值: 1. 返回None:繼續日後執行 2. 返回響應對象,直接跳出,按照process_response方法的順序執行 有條件觸發: 4. process_template_response(self,request,response) 1. 執行時間: 1. 視圖函數以後,而且返回的響應對象是要有render方法 2. 執行順序: 1. 按照註冊的倒序執行 3. 返回值: 1. 對傳遞過來的響應對象,調用其render方法,把返回值向後繼續傳遞 5. process_exception(self, request, exception) 1. 執行時間: 1. 當視圖函數中拋出異常的時候才執行 2. 執行順序: 1. 註冊的倒序 3. 參數和返回值 exception:視圖函數中拋出的異常 返回響應對象,就跳出按照process_response方法的順序執行 2. 額外補充 1. 反射 --> 由一個字符串找到方法、函數(可調用對象) 2. importlib --> 由字符串動態導入 **本身回去查 3. 示例: 限制用戶訪問我網站的頻率,一分鐘最多訪問3次 15:52:13 15:52:11 15:52:04 15:52:01 { '11.12.13.14': [15:52:11, 15:52:04, 15:52:01] } 4. ORM(多對多) 1. ORM多對多字段 # 多對多,自動幫咱們在數據庫創建第三張關係表 books = models.ManyToManyField(to='Book', related_name="authors") 參數: - to:表示和哪張表創建多對多的關係 - related_name:表示返鄉查詢時使用的那個字段名,默認反向查詢時使用表名_set的方式 2. 多對多字段的方法 1. 查詢 .all() --> 多對多查詢的方法, 2. 刪除 3. 添加新做者 1. 當form表單提交的數據是列表(多選的select\多選的checkbox)取值? request.POST.getlist("hobby") 2. .set([id1,id2,...]) 參數是一個列表 --> 刪除原來的設置新的 3. .add(id值) --> 在原來的基礎上增長新的紀錄 3. 13條 1. 返回QuerySet類型的 1. all() 2. filter() 3. exclude() 4. order_by() 5. reverse() 6. distinct() 7. values() -> QuerySet中是字典類型 8. values_list() -> QuerySet中是元祖類型 2. 返回具體對象的 1. get() 2. first() 3. last() 3. 返回數字 1. count() 4. 返回布爾值 1. exist() 5. ajax:https://www.cnblogs.com/liwenzhou/p/8718861.html 1. 目前已知瀏覽器和服務端發請求的方式 1. 瀏覽器地址欄 輸入url直接回車 GET 2. a標籤 GET 3. form表單 GET/POST 4. ajax GET/POST ajax的特色: 優勢: 1. 偷偷發請求,用戶無感知 2. 局部刷新 相對於其餘請求方式而言,返回的數據量小 3. 同一個頁面能夠發送屢次請求 異步 缺點: 1. 若是濫用,對服務端的壓力比較大 ajax的使用: jQuery版: 導入jQuery $.ajax({ url: "往哪裏發請求", type: "發送請求的類型", data: { }, success:function(res){ } }) ajax注意事項: data 6. jQuery:https://www.cnblogs.com/liwenzhou/p/8178806.html 1. 選擇器 1. 基本選擇器 1. id 2. 類 3. 標籤 4. 屬性 5. 組合 2. 層級選擇器 1. 後代選擇器 2. 毗鄰選擇器 3. 兒子選擇器 2. .text() 1. 獲取標籤的文本內容 $("div").text() --> 默認取全部div的文本內容 2. 有參數表示 設置標籤的文本內容 $("div").text(‘哈哈’) --> 設置全部div標籤的文本爲哈哈 3. .html() 1. 獲取標籤的html內容 $("div").html() --> 默認取第一個div的html內容 2. 有參數表示 設置標籤的html內容 $("div").html(‘哈哈’) --> 設置全部div標籤的html內容爲哈哈 4. val() 1. 獲取input標籤的值 $("input").val() --> 默認取第一個input的值 2. 有參數表示 設置input標籤的值 $("input").val(666) --> 設置全部input標籤的值爲666 AJAX上傳文件,下週再講 5. Form & ModelForm(下週再講) 技術的提高只是量的積累,思想的提高才是質的飛躍。 在公司混:政治正確纔是最重要的! 2. 練習題: 1. django請求生命週期 2. csrf原理 3. ORM和原生SQL區別? 4. django中裝飾器和中間件的應用場景? 5. 爲何要使用母板? 6. ORM查詢示例: 表結構: 出版社表: ID 名稱 圖書表: ID 書名稱 價格 出版社ID 做者表: ID 做者姓名 做者和圖書關係表: ID 圖書ID 做業ID 題目: 1. 查詢alex出過的全部書籍的名字(多對多) 2. 查詢alex的手機號 3. 查詢人民出版社出版過的全部書籍的名字以及做者的姓名 4. 統計每一本書的做者個數 5. 統計不止一個做者的圖書 6. 根據一本圖書做者數量的多少對查詢集 QuerySet進行排序 7. 查詢各個做者出的書的總價格 3. 做業:主機管理【03】:業務線管理 1. 基於django建立表: 用戶表:ID、用戶名、密碼 業務線表:ID、名稱 主機表:ID、主機名、密碼、業務線ID 用戶和業務線關係表:ID、業務線ID、管理員ID 2. 業務線管理:增刪改查(多對多) 3. 使用模板和動態路由 4. 主機管理使用CBV實現 5. 套用BootStrap樣式 採分點: 練習題:20 實現全部功能:70 代碼寫的清晰、健壯、可擴展:10
# 做業:引入框架模板----重要!!!2-3天---1.下次做業添加 0821 ok
# 新增功能:分頁 ok
# 需優化:1.cookie和session ---界面跳轉存在問題?
# 2.添加ajax局部刷新??
# 3.中間件???
# 4.刪除確認
# 重點關注一下 正向查詢、反向查詢、、、、
# cookie
# github
# 菜鳥教程---python,,,100例練習
'''
0809回顧
cookie
'''
'''
1.session
爲何要有session?
cookie的保存內容有限,只有4096;數據都保存在瀏覽器
原理
django中如何使用?
內容保存在數據庫的django_session中,k,v,超時時間
session把設置的kv數據保存在server端,cookie是存放在瀏覽器端
刪除過時的session
book_list註銷
session版登陸,本身書寫--ok
全局配置session
2.分頁
在腳本中操做orm,批量建立數據,提交
insert_book:設置環境,引入,建立數據
頁面實現
問題解決:輸入字母顯示第一頁;輸入很大的數字,取最後一頁
前端中有向上取整?ceil?
頁面按鈕問題:1.按鈕能動態切換顯示
2.頁面最多顯示11個:選中的高亮顯示active,頁碼顯示正常不出現0、55等,數據少時
3.顯示首頁和尾頁
4.添加上一頁、下一頁:第一頁不能點擊上一頁;最後一頁同理
---------看分裝以前代碼views
5.封裝成類@property 將方法變爲屬性,調用時就不用加()啦
出版社分頁,使用分裝的類;;須要添加a標籤對象鏈接地址
""" 那是一個上午, 寫了一個分頁的功能,特地封裝成了一個類工具,blablabla... """ # 封裝分頁類 class MyPage(object): def __init__(self, current_page, total_count, url_prefix, per_page=10, max_show=11): """ 初始化一個我本身定義的分頁實例 :param current_page: 當前頁碼 :param total_count: 總的數據量 :param url_prefix: 分頁中a標籤的url前綴 :param per_page: 每個顯示多少條數據 :param max_show: 頁面上最多顯示多少個頁碼 """ self.total_count = total_count self.per_page = per_page self.max_show = max_show self.url_prefix = url_prefix # 最多顯示頁碼數的一半 half_show = max_show // 2 # 由於URL取到的參數是字符串格式,須要轉換成int類型 try: current_page = int(current_page) except Exception as e: # 若是輸入的頁碼不是正經頁碼,默認展現第一頁 current_page = 1 # 求總共須要多少頁顯示 total_page, more = divmod(total_count, per_page) if more: total_page += 1 # 若是輸入的當前頁碼數大於總數據的頁碼數,默認顯示最後一頁 if current_page > total_page: current_page = total_page self.current_page = current_page # 計算一下顯示頁碼的起點和終點 show_page_start = current_page - half_show show_page_end = current_page + half_show # 特殊狀況特殊處理 # 1. 當前頁碼 - half_show <= 0 if current_page - half_show <= 0: show_page_start = 1 show_page_end = max_show # 2. 當前頁碼數 + hale_show >= total_page if current_page + half_show >= total_page: show_page_end = total_page show_page_start = total_page - max_show + 1 # 3. 總共須要的頁碼數 < max_show if total_page < max_show: show_page_start = 1 show_page_end = total_page self.show_page_start = show_page_start self.show_page_end = show_page_end self.total_page = total_page # 數據切片的起點 @property def start(self): return (self.current_page - 1) * self.per_page # 數據切片的終點 @property def end(self): return self.current_page * self.per_page # 分頁的html代碼 def page_html(self): tmp = [] page_html_start = '<nav aria-label="Page navigation" class="text-center"><ul class="pagination">' page_html_end = '</ul></nav>' tmp.append(page_html_start) # 添加一個首頁 tmp.append('<li><a href="/{}?page=1">首頁</a></li>'.format(self.url_prefix)) # 添加一個上一頁 # 噹噹前頁是第一頁的時候不能再點擊上一頁 if self.current_page - 1 <= 0: tmp.append( '<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a></li>') else: tmp.append( '<li><a href="/{}?page={}" aria-label="Previous"><span aria-hidden="true">«</span></a></li>'.format( self.url_prefix, self.current_page - 1)) # for循環添加要展現的頁碼 for i in range(self.show_page_start, self.show_page_end + 1): # 若是for循環的頁碼等於當前頁碼,給li標籤加一個active的樣式 if self.current_page == i: tmp.append('<li class="active"><a href="/{1}?page={0}">{0}</a></li>'.format(i, self.url_prefix)) else: tmp.append('<li><a href="/{1}?page={0}">{0}</a></li>'.format(i, self.url_prefix)) # 添加一個下一頁 # 當前 當前頁已是最後一頁,應該不讓下一頁按鈕能點擊 if self.current_page + 1 > self.total_page: tmp.append( '<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">»</span></a></li>') else: tmp.append( '<li><a href="/{}?page={}" aria-label="Previous"><span aria-hidden="true">»</span></a></li>'.format( self.url_prefix, self.current_page + 1)) # 添加一個尾頁 tmp.append('<li><a href="/{}?page={}">尾頁</a></li>'.format(self.url_prefix, self.total_page)) tmp.append(page_html_end) page_html = "".join(tmp) return page_html
from django.shortcuts import render from app01 import models from utils import mypage # Create your views here. def book_list(request): # 查找到全部的書籍 books = models.Book.objects.all() # 拿到總數據量 total_count = books.count() # 從url拿到page參數 current_page = request.GET.get("page", None) page_obj = mypage.MyPage(current_page, total_count, url_prefix="book_list", max_show=7) # 對總數據進行切片,拿到頁面顯示須要的數據 data = books[page_obj.start:page_obj.end] page_html = page_obj.page_html() return render(request, "book_list.html", {"books": data, "page_html": page_html}) def publisher_list(request): publishers = models.Publisher.objects.all() total_count = publishers.count() current_page = request.GET.get("page") # 三行完成分頁功能 page_obj = mypage.MyPage(current_page, total_count, url_prefix='publisher_list') data = publishers[page_obj.start:page_obj.end] page_html = page_obj.page_html() return render(request, "publisher_list.html", {"publishers": data, "page_html": page_html})
'''
# 註銷 def logout(request): # 清除session數據,讓cookie失效 request.session.flush() return redirect("/login/")
'''
3.中間件
importlib本身學習--本身練習代碼
5個使用中間件的方法:
process_request(self,request)
process_response(self,request,response)
哈哈----是嘿嘿的相應哈哈
1-3必需要會;4-5瞭解便可
例子--利用中間件,作頻率限制;動態配置頻率限制
4.orm多對多
建立庫以後,有sqlite3數據庫,才能在session中存取數據
用戶輸入的值,不要用get,用filter
列表--刪除--增長-修改
form表單提交的數據是列表(多選的select、checkbox)時,取值request.POST.getlist()
.set([]) 參數是一個列表,重置
.add([]) 增長
最難的地方,判斷書默認選中。
第三張表自動封裝了保存更新方法。
跨表查詢--要掌握
1. 基於對象的查詢
1. 正向查
2. 反向查
2. 基於QuerySet的查詢
1. 正向查
2. 反向查
'''
'''
5.ajax
JSON.parse 反序列化 字符串----對象
1.json內容回顧: 老師博客中有圖
2.ajax:偷偷發請求,用戶無感知;局部刷新,返回的數據量小;同一個頁面能夠發送屢次請求缺點:若是濫用,對服務端壓力較大ajax使用:jquery版導入;坑: 多餘一層的數據要使用json.stringify 保存setupajax ensure_csrf_cookie數據求和例子;用戶名校驗例子6.補充:jquery內容''''''下節:刪除確認-----------------------------AJAX上傳文件,下週再講--------------------- 5. Form & ModelForm(下週再講)'''