""" 異步提交 局部刷新
例子:github註冊 動態獲取用戶名實時的跟後端確認並實時展現的前端(局部刷新) 朝發送請求的方式 1.瀏覽器地址欄直接輸入url回車 GET請求 2.a標籤href屬性 GET請求 3.form表單 GET請求/POST請求 4.ajax GET請求/POST請求 AJAX 不是新的編程語言,而是一種使用現有標準的新方法(比較裝飾器) AJAX 最大的優勢是在不從新加載整個頁面的狀況下,能夠與服務器交換數據並更新部分網頁內容。(這一特色給用戶的感覺是在不知不覺中完成請求和響應過程) Ajax咱們只學習jQuery封裝以後的版本(不學原生的 原生的複雜而且在實際項目中也通常不用) 因此咱們在前端頁面使用ajax的時候須要確保導入了jQuery ps:並不僅有jQuery可以實現ajax,其餘的框架也能夠 可是換湯不換藥 原理是同樣的
咱們學的是jQuery版本的ajax,必需要確保html頁面已經提早加載了jQuery """
* JSON 使用 JavaScript 語法來描述數據對象,可是 JSON 仍然獨立於語言和平臺。JSON 解析器和 JSON 庫支持許多不一樣的編程語言。css
啥都別多說了,上圖吧!html
合格的json對象(json只認雙引的字符串格式):前端
["one", "two", "three"] { "one": 1, "two": 2, "three": 3 } {"names": ["張三", "李四"] } [ { "name": "張三"}, {"name": "李四"} ]
JavaScript中關於JSON對象和字符串轉換的兩個方法:python
JSON.parse(): 用於將一個 JSON 字符串轉換爲 JavaScript 對象(json只認雙引的字符串格式)jquery
JSON.parse('{"name":"Howker"}');
JSON.stringify(): 用於將 JavaScript 值轉換爲 JSON 字符串。git
JSON.stringify({"name":"Tonny"})
AJAX(Asynchronous Javascript And XML)翻譯成中文就是「異步的Javascript和XML」。即便用Javascript語言與服務器進行異步交互,傳輸的數據爲XML(固然,傳輸的數據不僅是XML)。github
AJAX 不是新的編程語言,而是一種使用現有標準的新方法。ajax
AJAX 最大的優勢是在不從新加載整個頁面的狀況下,能夠與服務器交換數據並更新部分網頁內容。(這一特色給用戶的感覺是在不知不覺中完成請求和響應過程)sql
AJAX 不須要任何瀏覽器插件,但須要用戶容許JavaScript在瀏覽器上執行。數據庫
$.ajax({ url:'', # 朝後端哪一個地址發送 跟action三種書寫方式一致 type:'get/post', # 提交方式 默認get 跟form表單method參數一致 data:{'username':'jason','password':123}, # 要發送的數據 success:function(args){ # 異步回調處理機制 } }) """ 當你在利用ajax進行先後端交互的時候 後端不管返回什麼都只會被回調函數接受 而再也不影響這個瀏覽器頁面了 """ # 擴展 參數 代碼發佈項目還會涉及 dataType:'json' """ 當後端是以HttpResponse返回的json格式的數據 默認是不會自動反序列化的 1.本身手動JSON.parse() 2.配置dataType參數 """
<script> $("#id_submit").click(function () { // 朝後端發送ajax請求 $.ajax({ // 一、指定朝哪一個後端發ajax請求 url:"", // 不寫就是朝當前地址提交 // 二、請求方式 type:"post", //不指定默認就是get,都是小寫,用ajax提交post數據,後端也是在request.POST中接收 dataType:"json", data:{ "username":$("#name").val(), "password":$("#password").val() }, // 四、回調函數:當後端給你返回結果的時候會自動觸發 args接收後端的返回結果 success:function (args) { console.log(args) // 經過DOM操做動態渲染到第三個input裏面 } }) .done(function(resp) { // 請求成功之後的操做 console.log(resp); }) .fail(function(error) { // 請求失敗之後的操做 console.log(error); }) }) </script>
# 結論:寫ajax的時候 你能夠直接將dataType參數加上 以防萬一 或者後端就用JsonResonse $.ajax({ url:'', # 朝後端哪一個地址發送 跟action三種書寫方式一致 type:'get/post', # 提交方式 默認get 跟form表單method參數一致 dataType:'JSON', data:{'username':'jason','password':123}, # 要發送的數據 success:function(args){ # 異步回調處理機制 } })
在不刷新的狀況下顯示計算結果到頁面上,頁面輸入兩個整數,經過AJAX傳輸到後端計算出結果並返回。(也不能在前端計算)
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), # ajax url(r'^ab_ajax/', views.ab_ajax), ]
views.py
from django.shortcuts import render,HttpResponse,redirect # Create your views here. def ab_ajax(request): # 和ajax交互的時候,不管返回什麼,都不會做用於瀏覽器,而是交給ajax的回調函數 if request.method == "POST": # print(request.POST) # <QueryDict: {'i1':['123'],'i2':['345']}> i1 = request.POST.get("i1") i2 = request.POST.get("i2") i3 = int(i1) + int(i2) return HttpResponse(i3) return render(request,"index.html")
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- Bootstrap3 核心 CSS 文件 --> <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <!-- jQuery文件。務必在bootstrap.min.js 以前引入 --> <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> <!-- Bootstrap3 核心 JavaScript 文件 --> <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <!-- font-awesome.min.css圖標庫4.7版本 --> <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> </head> <body> <input type="text" id="d1"> + <input type="text" id="d2"> = <input type="text" id="d3"> <p> <button id="btn">點我</button> </p> <script> // 先給按鈕綁定一個點擊事件 $("#btn").click(function () { // 朝後端發送ajax請求 $.ajax({ // 一、指定朝哪一個後端發ajax請求 url:"", // 不寫就是朝當前地址提交 // 二、請求方式 type:"post", //不指定默認就是get,都是小寫,用ajax提交post數據,後端也是在request.POST中接收 // 三、數據 data:{"i1":$("#d1").val(),"i2":$("#d2").val()}, // 四、回調函數:當後端給你返回結果的時候會自動觸發 args接收後端的返回結果 success:function (args) { $("#d3").val(args) // 經過DOM操做動態渲染到第三個input裏面 } }) }) </script> </body> </html>
# 針對後端若是是用HttpResponse返回的數據(json模塊序列化後) 回調函數不會自動幫你反序列化 # 若是後端直接用的是JsonResponse返回的數據 回調函數會自動幫你反序列化 # HttpResponse解決方式 1.本身在前端利用JSON.parse(args),手動反序列化 2.在ajax裏面配置一個參數 dataType:"json",
示例1:後端使用JsonResponse返回數據
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), # ajax url(r'^ab_ajax/', views.ab_ajax), ]
views.py
from django.shortcuts import render,HttpResponse,redirect from django.http import JsonResponse # Create your views here. def ab_ajax(request): # 和ajax交互的時候,不管返回什麼,都不會做用於瀏覽器,而是交給ajax的回調函數 if request.method == "POST": # print(request.POST) i1 = request.POST.get("i1") i2 = request.POST.get("i2") i3 = int(i1) + int(i2) d = {"code":100,"msg":i3} return JsonResponse(d) return render(request,"index.html")
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- Bootstrap3 核心 CSS 文件 --> <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <!-- jQuery文件。務必在bootstrap.min.js 以前引入 --> <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> <!-- Bootstrap3 核心 JavaScript 文件 --> <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <!-- font-awesome.min.css圖標庫4.7版本 --> <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> </head> <body> <input type="text" id="d1"> + <input type="text" id="d2"> = <input type="text" id="d3"> <p> <button id="btn">點我</button> </p> <script> // 先給按鈕綁定一個點擊事件 $("#btn").click(function () { // 朝後端發送ajax請求 $.ajax({ // 一、指定朝哪一個後端發ajax請求 url:"", // 不寫就是朝當前地址提交 // 二、請求方式 type:"post", //不指定默認就是get,都是小寫,用ajax提交post數據,後端也是在request.POST中接收 // 三、數據 data:{"i1":$("#d1").val(),"i2":$("#d2").val()}, // 四、回調函數:當後端給你返回結果的時候會自動觸發 args接收後端的返回結果 success:function (args) { {#$("#d3").val(args) // 經過DOM操做動態渲染到第三個input裏面#} console.log(typeof args) // 接收到的是對象類型 } }) }) </script> </body> </html>
示例2:後端用HttpResponse返回的數據(json序列化後的數據)
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), # ajax url(r'^ab_ajax/', views.ab_ajax), ]
views.py
from django.shortcuts import render,HttpResponse,redirect import json # Create your views here. def ab_ajax(request): # 和ajax交互的時候,不管返回什麼,都不會做用於瀏覽器,而是交給ajax的回調函數 if request.method == "POST": # print(request.POST) i1 = request.POST.get("i1") i2 = request.POST.get("i2") i3 = int(i1) + int(i2) d = {"code":100,"msg":i3} return HttpResponse(json.dumps(d)) return render(request,"index.html")
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- Bootstrap3 核心 CSS 文件 --> <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <!-- jQuery文件。務必在bootstrap.min.js 以前引入 --> <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> <!-- Bootstrap3 核心 JavaScript 文件 --> <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <!-- font-awesome.min.css圖標庫4.7版本 --> <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> </head> <body> <input type="text" id="d1"> + <input type="text" id="d2"> = <input type="text" id="d3"> <p> <button id="btn">點我</button> </p> <script> // 先給按鈕綁定一個點擊事件 $("#btn").click(function () { // 朝後端發送ajax請求 $.ajax({ // 一、指定朝哪一個後端發ajax請求 url:"", // 不寫就是朝當前地址提交 // 二、請求方式 type:"post", //不指定默認就是get,都是小寫,用ajax提交post數據,後端也是在request.POST中接收 // 三、數據 data:{"i1":$("#d1").val(),"i2":$("#d2").val()}, // 四、回調函數:當後端給你返回結果的時候會自動觸發 args接收後端的返回結果 dataType:"json", success:function (args) { {#$("#d3").val(args) // 經過DOM操做動態渲染到第三個input裏面#} console.log(typeof args) // 接收到的是對象類型 } }) }) </script> </body> </html>
# 咱們主要研究post請求數據的編碼格式 """ get請求數據就是直接放在url後面的 url?username=jason&password=123 """
能夠朝後端發送post請求的方式
# 1.form表單 # 2.ajax請求
朝後端傳輸數據的編碼格式
# 1.urlencoded # 2.formdata # 3.json
知識點:
# 默認的數據編碼格式是urlencoded 數據格式:username=jason&password=123 django後端針對符合urlencoded編碼格式的數據都會自動幫你解析封裝到request.POST中 username=jason&password=123 >>> request.POST # 若是你把編碼格式改爲formdata,那麼針對普通的鍵值對仍是解析到request.POST中而將文件解析到request.FILES中 form表單是沒有辦法發送json格式數據的
查看數據編碼格式:
查看數據格式:
知識點:
# 默認的編碼格式也是urlencoded 數據格式:username=jason&age=20 django後端針對符合urlencoded編碼格式的數據都會自動幫你解析封裝到request.POST中 username=jason&age=20 >>> request.POST
# 宗旨: 先後端傳輸數據的時候必定要確保編碼格式跟數據真正的格式是一致的 不要騙人家!!! # ajax朝後端發送的json數據:(注意要先將data數據序列化成json格式字符串) 格式:{"username":"jason","age":25} 後端在request.POST裏面確定找不到 由於django針對json格式的數據 不會作任何的處理,會存放在request.body中(二進制形式)b'{"username":"jason","age":25}' # request對象方法補充 request.is_ajax() 判斷當前請求是不是ajax請求 返回布爾值
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), # ajax發送json格式數據 url(r'^ab_json/', views.ab_json), ]
views.py
from django.shortcuts import render # Create your views here. def ab_json(request): import json if request.is_ajax(): # 判斷當前請求是不是ajax請求 返回布爾值
# 針對json格式數據須要手動處理,django不會作任何處理,存放在request.body json_bytes = request.body # b'{"username":"jason","age":25}' # 反序列化方式一:先decode解碼再loads反序列化 # json_str = json_bytes.decode('utf-8') # json_dict = json.loads(json_str) # 反序列化方式二:json.loads括號內若是傳入了一個二進制格式的數據那麼內部自動解碼再反序列化 json_dict = json.loads(json_bytes) print(json_dict,type(json_dict)) return render(request,"ab_json.html")
ab_json.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- Bootstrap3 核心 CSS 文件 --> <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <!-- jQuery文件。務必在bootstrap.min.js 以前引入 --> <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> <!-- Bootstrap3 核心 JavaScript 文件 --> <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <!-- font-awesome.min.css圖標庫4.7版本 --> <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> </head> <body> <button class="btn btn-danger" id="d1">點我</button> <script> $("#d1").click(function () { $.ajax({ url:"", type:"post", data:JSON.stringify({"username":"jason","age":20}), // 序列化爲json格式字符串 dataType:'JSON',
contentType:"application/json", // 編碼格式改成json,指定編碼格式,默認是urlencoded格式 success:function (args) { } }) }) </script> </body> </html>
# ajax發送json格式數據須要注意點 1.contentType參數指定成:application/json 2.數據是真正的json格式數據 3.django後端不會幫你處理json格式數據須要你本身去request.body獲取並處理
""" ajax發送文件須要藉助於js內置對象FormData """
示例:
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), # ajax發送文件 url(r'^ab_file/', views.ab_file), ]
views.py
from django.shortcuts import render # Create your views here. def ab_file(request): if request.is_ajax(): if request.method == 'POST': print(request.POST) print(request.FILES) return render(request,"ab_file.html")
ab_file.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- Bootstrap3 核心 CSS 文件 --> <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <!-- jQuery文件。務必在bootstrap.min.js 以前引入 --> <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> <!-- Bootstrap3 核心 JavaScript 文件 --> <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <!-- font-awesome.min.css圖標庫4.7版本 --> <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> </head> <body> <p>usernmae:<input type="text" id="d1"></p> <p>password:<input type="text" id="d2"></p> <p><input type="file" id="d3"></p> <button class="btn btn-info" id="d4">點我</button> <script> // 點擊按鈕朝後端發送普通鍵值對和文件數據 $("#d4").on("click",function () { // 1.須要先利用FormData內置對象 let formDateObj = new FormData(); // 2.添加普通的鍵值對 formDateObj.append('username',$('#d1').val()); formDateObj.append('password',$('#d2').val()); // 3.添加文件對象,$('#d3')[0]先將jQuery對象轉換爲DOM對象 formDateObj.append('myfile',$('#d3')[0].files[0]) // 4.將對象基於ajax發送給後端 $.ajax({ url:'', type:'post', data:formDateObj, // 直接將對象放在data後面便可 dataType:'JSON', // ajax發送文件必需要指定的兩個參數 contentType:false, // 不需使用任何編碼 django後端可以自動識別formdata對象 processData:false, // 告訴你的瀏覽器不要對你的數據進行任何處理 success:function (args) { } }) }) </script> </body> </html>
# 總結: 1.須要利用內置對象FormData // 2 添加普通的鍵值對 formDateObj.append('username',$('#d1').val()); formDateObj.append('password',$('#d2').val()); // 3 添加文件對象 formDateObj.append('myfile',$('#d3')[0].files[0]) 2.須要指定兩個關鍵性的參數 contentType:false, // 不需使用任何編碼 django後端可以自動識別formdata對象 processData:false, // 告訴你的瀏覽器不要對你的數據進行任何處理 3.django後端可以直接識別到formdata對象而且可以將內部的普通鍵值自動解析並封裝到request.POST中 文件數據自動解析並封裝到request.FILES中
""" 若是發現你能夠直接使用MySQL可是沒法使用sqlite3 不要慌張不要恐懼 你只須要按照以前MySQL的操做將sqlite3的驅動裝一下便可 """ # 需求:在前端給我獲取到後端用戶表裏面全部的數據 而且要是列表套字典
示例:
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), # 序列化組件相關 url(r'^ab_ser/', views.ab_ser), ]
views.py
from django.shortcuts import render,HttpResponse from app01 import models from django.http import JsonResponse from django.core import serializers # 序列化組件serializers # Create your views here. def ab_ser(request): user_queryset = models.User.objects.all() # 需求返回[{},{},{},{},{}]格式 # 方法一:手動實現 # user_list = [] # for user_obj in user_queryset: # tmp = { # 'pk':user_obj.pk, # 'username':user_obj.username, # 'age':user_obj.age, # 'gender':user_obj.get_gender_display(), # } # user_list.append(tmp) # # return JsonResponse(user_list,safe=False) # 方法二:序列化 res = serializers.serialize('json',user_queryset) # 第一個參數:序列化成什麼格式,第二個參數:要序列化的數據 return HttpResponse(res) """ 先後端分離的項目 做爲後端開發的你只須要寫代碼將數據處理好 可以序列化返回給前端便可 再寫一個接口文檔 告訴前端每一個字段表明的意思便可 # 手動實現 [ { "pk": 1, "username": "jason", "age": 20, "gender": "male" }, { "pk": 2, "username": "egon", "age": 22, "gender": "female" }, { "pk": 3, "username": "tank", "age": 25, "gender": "male" }, { "pk": 4, "username": "lxx", "age": 30, "gender": "other" } ] 使用serializers序列化 [ { "model": "app01.user", "pk": 1, "fields": { "username": "jason", "age": 20, "gender": 1 } }, { "model": "app01.user", "pk": 2, "fields": { "username": "egon", "age": 22, "gender": 2 } }, { "model": "app01.user", "pk": 3, "fields": { "username": "tank", "age": 25, "gender": 1 } }, { "model": "app01.user", "pk": 4, "fields": { "username": "lxx", "age": 30, "gender": 3 } } ] 寫接口就是利用序列化組件渲染數據而後寫一個接口文檔 該交代交代一下就完事了 """
""" 本身要學會如何拷貝 學會基於別人的基礎之上作修改 研究各個參數表示的意思 而後找葫蘆畫瓢 """
示例:
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), # 用戶展現頁 url(r'^user/list/', views.user_list), # 刪除用戶 url(r'^delete/user/',views.delete_user), ]
views.py
from django.shortcuts import render,HttpResponse from django.http import JsonResponse from app01 import models import time # Create your views here. def user_list(request): user_queryset = models.User.objects.all() return render(request,"user_list.html",locals()) def delete_user(request): """ 先後端在用ajax進行交互的時候 後端一般給ajax的回調函數返回一個字典格式的數據 """ if request.is_ajax(): if request.method == 'POST': back_dic = {"code":1000,'msg':''} time.sleep(3) # 模擬操做數據的延遲 delete_id = request.POST.get('delete_id') models.User.objects.filter(pk=delete_id).delete() back_dic['msg'] = '數據已經刪了,你趕忙跑路!' # 咱們須要告訴前端咱們操做的結果 return JsonResponse(back_dic)
user_list.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> {% load static %} <!-- Bootstrap3 核心 CSS 文件 --> <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <!-- jQuery文件。務必在bootstrap.min.js 以前引入 --> <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> <!-- Bootstrap3 核心 JavaScript 文件 --> <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <!-- font-awesome.min.css圖標庫4.7版本 --> <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> <link rel="stylesheet" href="{% static "bootstrap-sweetalert-master/dist/sweetalert.css" %}"> <script src="{% static "bootstrap-sweetalert-master/dist/sweetalert.min.js" %}"></script> </head> <body> <h1 class="text-center">數據展現</h1> <div class="row"> <div class="col-md-8 col-md-offset-2"> <table class="table-striped table table-hover"> <thead> <tr> <th>ID</th> <th>username</th> <th>age</th> <th>gender</th> <th>actions</th> </tr> </thead> <tbody> {% for user_obj in user_queryset %} <tr> <td>{{ user_obj.pk }}</td> <td>{{ user_obj.username }}</td> <td>{{ user_obj.age }}</td> <td>{{ user_obj.get_gender_display }}</td> <td> <button class="btn btn-primary btn-xs">編輯</button> <button class="btn btn-danger btn-xs del" delete_id="{{ user_obj.pk }}">刪除</button> </td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> <script> $('.del').on('click',function () { // 先將當前標籤對象存儲起來 let currentBtn = $(this); // this指代當前被操做對象自己 // 二次確認彈框 swal({ title: "你肯定要刪嗎?", text: "刪除可就找不回來了哦!", type: "warning", showCancelButton: true, // 是否顯示取消按鈕 confirmButtonClass: "btn-danger", // 確認按鈕的樣式類 confirmButtonText: "刪除", // 確認按鈕文本 cancelButtonText: "取消", // 取消按鈕文本 closeOnConfirm: false, closeOnCancel: false, showLoaderOnConfirm: true // 顯示正在刪除的動畫效果 // 等待後端處理時間 。。。動畫 }, function(isConfirm) { // isConfirm 是用來判斷用戶是否點了確認 if (isConfirm) { // 朝後端發送ajax請求刪除數據以後 再彈下面的提示框 $.ajax({ {#url:'/delete/user/' + currentBtn.attr('delete_id'), // 1 傳遞主鍵值方式1#} url:'/delete/user/', // 2 方式2,放在data裏面 type:'post', data:{'delete_id':currentBtn.attr('delete_id')}, success:function (args) { // args = {'code':'','msg':''} // 判斷響應狀態碼 而後作不一樣的處理 if(args.code === 1000){ swal("刪了!", args.msg, "success"); // 1.lowb版本 直接刷新當前頁面 {#window.location.reload()#} // 2.利用DOM操做 動態刷新 經過當前被操做對象,移動到數據那一行對應的標籤,刪除行標籤 currentBtn.parent().parent().remove() }else{ swal('完了','出現了未知的錯誤','info') } } }) } else { swal("慫逼", "不要說我認識你", "error"); } }); }) </script> </body> </html>
解決方法:
一、先找到被遮擋文字的標籤位置
二、在user_list.html頁面中添加內部css樣式表,爲找到的標籤添加一個上填充padding
<style> div.sweet-alert h2 { padding-top: 10px; } </style>
res = confirm() if(res){ $.ajax({}) }else{ 不發 }
# 訪問url的時候 # 先Book表插入1000條數據 # 再將說有的數據查詢並展現到前端頁面
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), # 批量插入 url(r'^ab_batch',views.ab_batch), ]
views.py
from django.shortcuts import render,HttpResponse from django.http import JsonResponse from app01 import models # Create your views here. def ab_batch(request): # 先Book表插入1000條數據 for i in range(1000): models.Book.objects.create(title="第%s本書" %i) # 再將說有的數據查詢並展現到前端頁面 book_queryset = models.Book.objects.all() return render(request,"ab_batch.html",locals())
ab_batch.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- Bootstrap3 核心 CSS 文件 --> <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <!-- jQuery文件。務必在bootstrap.min.js 以前引入 --> <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> <!-- Bootstrap3 核心 JavaScript 文件 --> <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <!-- font-awesome.min.css圖標庫4.7版本 --> <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> </head> <body> {% for book_obj in book_queryset %} <p>{{ book_obj.title }}</p> {% endfor %} </body> </html>
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), # 批量插入 url(r'^ab_batch',views.ab_batch), ]
views.py
from django.shortcuts import render,HttpResponse from django.http import JsonResponse from app01 import models # Create your views here. def ab_batch(request): book_list = [] for i in range(10000): book_obj = models.Book(title="第%s本書" %i) book_list.append(book_obj) # 上面兩行能夠直接縮寫成一行 # book_list.append(models.Book(title="第%s本書" %i)) # 一次性插入 models.Book.objects.bulk_create(book_list) # 再將說有的數據查詢並展現到前端頁面 book_queryset = models.Book.objects.all() return render(request,"ab_batch.html",locals())
ab_batch.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- Bootstrap3 核心 CSS 文件 --> <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <!-- jQuery文件。務必在bootstrap.min.js 以前引入 --> <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> <!-- Bootstrap3 核心 JavaScript 文件 --> <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <!-- font-awesome.min.css圖標庫4.7版本 --> <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> </head> <body> {% for book_obj in book_queryset %} <p>{{ book_obj.title }}</p> {% endfor %} </body> </html>
# 當你想要批量插入數據的時候 使用orm給你提供的bulk_create可以大大的減小操做時間
""" 總數據100 每頁展現10 須要10 總數據101 每頁展現10 須要11 總數據99 每頁展現10 須要10 如何經過代碼動態的計算出到底須要多少頁? 在製做頁碼個數的時候 通常狀況下都是奇數個 符合對稱美的標準 """
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), # 分頁 url(r'^ab_batch',views.ab_batch), ]
views.py
from django.shortcuts import render,HttpResponse from django.http import JsonResponse from app01 import models def ab_batch(request): # 分頁器推導 book_list = models.Book.objects.all() # 想訪問哪一頁 current_page = request.GET.get('page', 1) # 若是獲取不到當前頁碼 就展現第一頁 # 數據類型轉換 try: current_page = int(current_page) except Exception: current_page = 1 # 每頁展現多少條 per_page_num = 10 # 起始位置 start_page = (current_page - 1) * per_page_num # 終止位置 end_page = current_page * per_page_num # 計算出到底須要多少頁 all_count = book_list.count() page_count, more = divmod(all_count, per_page_num) if more: page_count += 1 if current_page <= 1: prev_page = '<li class="disabled"><a href="#">上一頁</a></li>' else: prev_page = '<li><a href="?page=%s">上一頁</a></li>' % (current_page - 1,) page_html = '' current_page_new = current_page if current_page < 6: current_page = 6 for i in range(current_page - 5, current_page + 6): if current_page_new == i: page_html += '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i) else: page_html += '<li><a href="?page=%s">%s</a></li>' % (i, i) if current_page >= page_count: next_page = '<li class="disabled"><a href="#">下一頁</a></li>' else: next_page = '<li><a href="?page=%s">下一頁</a></li>' % (current_page + 1,) book_queryset = book_list[start_page:end_page] return render(request,"ab_batch.html",locals()) ''' per_page_num = 10 current_page start_page end_page 1 0 10 2 10 20 3 20 30 4 30 40 per_page_num = 5 current_page start_page end_page 1 0 5 2 5 10 3 15 20 4 25 30 規律: start_page = (current_page - 1) * per_page_num end_page = current_page * per_page_num '''
ab_batch.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- Bootstrap3 核心 CSS 文件 --> <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <!-- jQuery文件。務必在bootstrap.min.js 以前引入 --> <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> <!-- Bootstrap3 核心 JavaScript 文件 --> <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <!-- font-awesome.min.css圖標庫4.7版本 --> <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> </head> <body> {% for book_obj in book_queryset %} <p>{{ book_obj.title }}</p> {% endfor %} <div class="text-center"> <nav aria-label="Page navigation"> <ul class="pagination "> <li><a href="?page=1">首頁</a></li> {{ prev_page|safe }} {{ page_html|safe }} {{ next_page|safe }} <li><a href="?page={{ page_count }}">尾部</a></li> </ul> </nav> </div> </body> </html>
1.queryset對象是直接切片操做的 2.用戶到底要訪問哪一頁 如何肯定? url?page=1 current_page = request.GET.get('page',1) # 獲取到的數據都是字符串類型 你須要注意類型轉換 3.本身規定每頁展現多少條數據 per_page_num = 10 4.切片的起始位置和終止位置 start_page = (current_page - 1)* per_page_num end_page = current_page * per_page_num # 利用簡單找規律 找出上述四個參數的規律 5.當前數據的總條數 book_queryset.count() 6.如何肯定總共須要多少頁才能展現完全部的數據 # 利用python內置函數divmod() page_count, more = divmod(all_count,per_page_num) if more: page_count += 1 7.前端模版語法是沒有range功能的 # 前端代碼不必定非要在前端書寫 也能夠在後端生成傳遞給頁面 8.針對須要展現的頁碼須要你本身規劃好到底展現多少個頁碼 # 通常狀況下頁碼的個數設計都是奇數(符合審美標準) 11個頁碼 當前頁減5 當前頁加6 你能夠給標籤價樣式從而讓選中的頁碼高亮顯示 9.針對頁碼小於6的狀況 你須要作處理 不能再減
初級版是自定義分頁器開發流程的基本思路,咱們不須要掌握代碼的編寫,只須要掌握基本用法便可
自定義分頁器封裝代碼
注意:
自定義的分頁器是基於bootstrap樣式來的 因此須要提早導入bootstrap
bootstrap 版本 v3
jQuery 版本 v3
# 分頁器 class Pagination(object): def __init__(self, current_page, all_count, per_page_num=2, pager_count=11): """ 封裝分頁相關數據 :param current_page: 當前頁 :param all_count: 數據庫中的數據總條數 :param per_page_num: 每頁顯示的數據條數 :param pager_count: 最多顯示的頁碼個數 """ try: current_page = int(current_page) except Exception as e: current_page = 1 if current_page < 1: current_page = 1 self.current_page = current_page self.all_count = all_count self.per_page_num = per_page_num # 總頁碼 all_pager, tmp = divmod(all_count, per_page_num) if tmp: all_pager += 1 self.all_pager = all_pager self.pager_count = pager_count self.pager_count_half = int((pager_count - 1) / 2) @property def start(self): return (self.current_page - 1) * self.per_page_num @property def end(self): return self.current_page * self.per_page_num def page_html(self): # 若是總頁碼 < 11個: if self.all_pager <= self.pager_count: pager_start = 1 pager_end = self.all_pager + 1 # 總頁碼 > 11 else: # 當前頁若是<=頁面上最多顯示11/2個頁碼 if self.current_page <= self.pager_count_half: pager_start = 1 pager_end = self.pager_count + 1 # 當前頁大於5 else: # 頁碼翻到最後 if (self.current_page + self.pager_count_half) > self.all_pager: pager_end = self.all_pager + 1 pager_start = self.all_pager - self.pager_count + 1 else: pager_start = self.current_page - self.pager_count_half pager_end = self.current_page + self.pager_count_half + 1 page_html_list = [] # 添加前面的nav和ul標籤 page_html_list.append(''' <nav aria-label='Page navigation>' <ul class='pagination'> ''') first_page = '<li><a href="?page=%s">首頁</a></li>' % (1) page_html_list.append(first_page) if self.current_page <= 1: prev_page = '<li class="disabled"><a href="#">上一頁</a></li>' else: prev_page = '<li><a href="?page=%s">上一頁</a></li>' % (self.current_page - 1,) page_html_list.append(prev_page) for i in range(pager_start, pager_end): if i == self.current_page: temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,) else: temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,) page_html_list.append(temp) if self.current_page >= self.all_pager: next_page = '<li class="disabled"><a href="#">下一頁</a></li>' else: next_page = '<li><a href="?page=%s">下一頁</a></li>' % (self.current_page + 1,) page_html_list.append(next_page) last_page = '<li><a href="?page=%s">尾頁</a></li>' % (self.all_pager,) page_html_list.append(last_page) # 尾部添加標籤 page_html_list.append(''' </ul> </nav> ''') return ''.join(page_html_list)
""" 當咱們須要使用到非django內置的第三方功能或者組件代碼的時候 咱們通常狀況下會在項目根目錄建立一個名爲utils文件夾 在該文件夾內對模塊進行功能性劃分 utils也能夠能夠在每一個應用下建立 具體結合實際狀況 咱們到了後期封裝代碼的時候 再也不侷限於函數 仍是儘可能朝面向對象去封裝 咱們自定義的分頁器是基於bootstrap樣式來的 因此你須要提早導入bootstrap bootstrap 版本 v3 jQuery 版本 v3 """
一、在django項目根目錄或app01應用目錄新建一個utils文件夾用於存放第三方功能或模塊
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), # 分頁 url(r'^ab_batch',views.ab_batch), ]
mypage.py
# 分頁器 class Pagination(object): def __init__(self, current_page, all_count, per_page_num=2, pager_count=11): """ 封裝分頁相關數據 :param current_page: 當前頁 :param all_count: 數據庫中的數據總條數 :param per_page_num: 每頁顯示的數據條數 :param pager_count: 最多顯示的頁碼個數 """ try: current_page = int(current_page) except Exception as e: current_page = 1 if current_page < 1: current_page = 1 self.current_page = current_page self.all_count = all_count self.per_page_num = per_page_num # 總頁碼 all_pager, tmp = divmod(all_count, per_page_num) if tmp: all_pager += 1 self.all_pager = all_pager self.pager_count = pager_count self.pager_count_half = int((pager_count - 1) / 2) @property def start(self): return (self.current_page - 1) * self.per_page_num @property def end(self): return self.current_page * self.per_page_num def page_html(self): # 若是總頁碼 < 11個: if self.all_pager <= self.pager_count: pager_start = 1 pager_end = self.all_pager + 1 # 總頁碼 > 11 else: # 當前頁若是<=頁面上最多顯示11/2個頁碼 if self.current_page <= self.pager_count_half: pager_start = 1 pager_end = self.pager_count + 1 # 當前頁大於5 else: # 頁碼翻到最後 if (self.current_page + self.pager_count_half) > self.all_pager: pager_end = self.all_pager + 1 pager_start = self.all_pager - self.pager_count + 1 else: pager_start = self.current_page - self.pager_count_half pager_end = self.current_page + self.pager_count_half + 1 page_html_list = [] # 添加前面的nav和ul標籤 page_html_list.append(''' <nav aria-label='Page navigation>' <ul class='pagination'> ''') first_page = '<li><a href="?page=%s">首頁</a></li>' % (1) page_html_list.append(first_page) if self.current_page <= 1: prev_page = '<li class="disabled"><a href="#">上一頁</a></li>' else: prev_page = '<li><a href="?page=%s">上一頁</a></li>' % (self.current_page - 1,) page_html_list.append(prev_page) for i in range(pager_start, pager_end): if i == self.current_page: temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,) else: temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,) page_html_list.append(temp) if self.current_page >= self.all_pager: next_page = '<li class="disabled"><a href="#">下一頁</a></li>' else: next_page = '<li><a href="?page=%s">下一頁</a></li>' % (self.current_page + 1,) page_html_list.append(next_page) last_page = '<li><a href="?page=%s">尾頁</a></li>' % (self.all_pager,) page_html_list.append(last_page) # 尾部添加標籤 page_html_list.append(''' </ul> </nav> ''') return ''.join(page_html_list)
views.py後端使用
from django.shortcuts import render,HttpResponse from django.http import JsonResponse from app01 import models from utils.mypage import Pagination # 導入分頁器,這裏utils文件夾在根目錄下,若是在app01應用目錄下使用from app01.utils.mypage import Pagination def ab_batch(request): # 分頁器推導 book_list = models.Book.objects.all() # 想訪問哪一頁 current_page = request.GET.get('page', 1) # 若是獲取不到當前頁碼 就展現第一頁 # 計算出到底須要多少頁 all_count = book_list.count() page_obj = Pagination(current_page=current_page, all_count=all_count, per_page_num=10) page_queryset = book_list[page_obj.start:page_obj.end] return render(request, 'ab_batch.html', locals())
前端
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- Bootstrap3 核心 CSS 文件 --> <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <!-- jQuery文件。務必在bootstrap.min.js 以前引入 --> <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> <!-- Bootstrap3 核心 JavaScript 文件 --> <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <!-- font-awesome.min.css圖標庫4.7版本 --> <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> </head> <body> {% for book_obj in book_queryset %} <p>{{ book_obj.title }}</p> {% endfor %} <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> {% for book in page_queryset %} <p>{{ book.title }}</p> {% endfor %}
<div class="text-center"> {{ page_obj.page_html|safe }}
</div> </div> </div> </div> </body> </html>
在頁面顯示分頁數據,須要用到Django分頁器組件
from django.core.paginator import Paginator
Paginator對象: paginator = Paginator(user_list, 10) # per_page: 每頁顯示條目數量 # count: 數據總個數 # num_pages:總頁數 # page_range:總頁數的索引範圍,如: (1,10),(1,200) # page: page對象 page對象:page=paginator.page(1) # has_next 是否有下一頁 # next_page_number 下一頁頁碼 # has_previous 是否有上一頁 # previous_page_number 上一頁頁碼 # object_list 分頁以後的數據列表 # number 當前頁 # paginator paginator對象
from django.shortcuts import render,HttpResponse # Create your views here. from app01.models import * from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger def index(request): ''' 批量導入數據: Booklist=[] for i in range(100): Booklist.append(Book(title="book"+str(i),price=30+i*i)) Book.objects.bulk_create(Booklist) ''' ''' 分頁器的使用: book_list=Book.objects.all() paginator = Paginator(book_list, 10) print("count:",paginator.count) #數據總數 print("num_pages",paginator.num_pages) #總頁數 print("page_range",paginator.page_range) #頁碼的列表 page1=paginator.page(1) #第1頁的page對象 for i in page1: #遍歷第1頁的全部數據對象 print(i) print(page1.object_list) #第1頁的全部數據 page2=paginator.page(2) print(page2.has_next()) #是否有下一頁 print(page2.next_page_number()) #下一頁的頁碼 print(page2.has_previous()) #是否有上一頁 print(page2.previous_page_number()) #上一頁的頁碼 # 拋錯 #page=paginator.page(12) # error:EmptyPage #page=paginator.page("z") # error:PageNotAnInteger ''' book_list=Book.objects.all() paginator = Paginator(book_list, 10) page = request.GET.get('page',1) currentPage=int(page) try: print(page) book_list = paginator.page(page) except PageNotAnInteger: book_list = paginator.page(1) except EmptyPage: book_list = paginator.page(paginator.num_pages) return render(request,"index.html",{"book_list":book_list,"paginator":paginator,"currentPage":currentPage})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> <div class="container"> <h4>分頁器</h4> <ul> {% for book in book_list %} <li>{{ book.title }} -----{{ book.price }}</li> {% endfor %} </ul> <ul class="pagination" id="pager"> {% if book_list.has_previous %} <li class="previous"><a href="/index/?page={{ book_list.previous_page_number }}">上一頁</a></li> {% else %} <li class="previous disabled"><a href="#">上一頁</a></li> {% endif %} {% for num in paginator.page_range %} {% if num == currentPage %} <li class="item active"><a href="/index/?page={{ num }}">{{ num }}</a></li> {% else %} <li class="item"><a href="/index/?page={{ num }}">{{ num }}</a></li> {% endif %} {% endfor %} {% if book_list.has_next %} <li class="next"><a href="/index/?page={{ book_list.next_page_number }}">下一頁</a></li> {% else %} <li class="next disabled"><a href="#">下一頁</a></li> {% endif %} </ul> </div> </body> </html>
核心邏輯
''' 顯示左5,右5,總共11個頁, 1 若是總頁碼大於11 1.1 if 當前頁碼減5小於1,要生成1到12的列表(顧頭不顧尾,共11個頁碼) page_range=range(1,12) 1.2 elif 當前頁碼+5大於總頁碼,生成當前頁碼減10,到當前頁碼加1的列表(顧頭不顧尾,共11個頁碼) page_range=range(paginator.num_pages-10,paginator.num_pages+1) 1.3 else 生成當前頁碼-5,到當前頁碼+6的列表 page_range=range(current_page_num-5,current_page_num+6) 2 其它狀況,生成的列表就是pageinator的page_range page_range=paginator.page_range '''
視圖層
def page_test(request): # book_list=[] # for i in range(100): # book=Book(name='book%s'%i,price=10+i,pub_date='2018-09-18',publish_id=1) # book_list.append(book) # Book.objects.bulk_create(book_list,10) book_list=Book.objects.all() # 生成paginator對象,傳入書籍列表,每頁10條數據 paginator=Paginator(book_list,3) # 總頁碼數 print(paginator.num_pages) # 頁碼列表 print(paginator.page_range) # 總數據 print(paginator.count) # 獲取頁面傳來的頁碼 current_page=int(request.GET.get('page',1)) page_range=[] # 左5 右5 # 獲取頁面傳來的頁碼的page對象 try: page=paginator.page(current_page) # print(page.has_next()) #是否有下一頁 # print(page.next_page_number()) #下一頁的頁碼 # print(page.has_previous()) #是否有上一頁 # print(page.previous_page_number()) #上一頁的頁碼 # 循環打印出當頁對象 for i in page: print(i) except Exception as e: current_page=1 page = paginator.page(1) if paginator.num_pages>11: if current_page+5>paginator.num_pages: page_range=range(paginator.num_pages-10,paginator.num_pages+1) elif current_page-5<1: page_range=range(1,12) else: page_range=range(current_page-5,current_page+6) else: page_range=paginator.page_range return render(request,'page_test.html',locals())
模板層
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css"> <title>Title</title> </head> <body> <ul> {% for foo in page %} <li>{{ foo.name }}</li> {% endfor %} </ul> <nav aria-label="Page navigation"> <ul class="pagination"> {% if page.has_previous %} <li> <a href="/page_test/?page={{ page.previous_page_number }}" aria-label="Previous"> <span aria-hidden="true">上一頁</span> </a> </li> {% else %} <li class="disabled"> <a href="#" aria-label="Previous"> <span aria-hidden="true">上一頁</span> </a> </li> {% endif %} {% for foo in page_range %} {% if current_page == foo %} <li class="active"><a href="/page_test/?page={{ foo }}">{{ foo }}</a></li> {% else %} <li><a href="/page_test/?page={{ foo }}">{{ foo }}</a></li> {% endif %} {% endfor %} {% if page.has_next %} <li> <a href="/page_test/?page={{ page.next_page_number }}" aria-label="Next"> <span aria-hidden="true">下一頁</span> </a> </li> {% else %} <li class="disabled"> <a href="#" aria-label="Next"> <span aria-hidden="true">下一頁</span> </a> </li> {% endif %} </ul> </nav> </body> </html>