AJAX(Asynchronous Javascript And XML)翻譯成中文就是「異步的Javascript和XML」。即便用Javascript語言與服務器進行異步交互,傳輸的數據爲XML(固然,傳輸的數據不僅是XML)。前端
AJAX 不是新的編程語言,而是一種使用現有標準的新方法。其實就是基於js寫的一個功能模塊而已python
因爲原生js書寫ajax較爲繁瑣 因此咱們直接學jQuery封裝號的ajax模塊操做ajax
AJAX 最大的優勢是:異步提交,局部刷新數據庫
在不從新加載整個頁面的狀況下,能夠與服務器交換數據並更新部分網頁內容。(這一特色給用戶的感覺是在不知不覺中完成請求和響應過程)
AJAX 不須要任何瀏覽器插件,但須要用戶容許JavaScript在瀏覽器上執行。django
同步交互:任務提交以後原地等待任務的返回結果 進程表現上來講 阻塞 異步交互:任務提交以後不須要原地等待返回結果 直接執行下一行代碼 進程表現上來講 非阻塞 任務的結果經過異步回調機制 callback()
案例:用戶名在時時和後端交互,可是頁面沒有刷新。用戶體驗更好編程
前端與後端的交互方式有:json
1.瀏覽器窗口輸入url回車 GET 2.a標籤href屬性填寫url點擊 GET 3.form表單 GET/POST 4.Ajax GET/POST
小案例:後端
初識ajax 案例:頁面上有三個input框 一個按鈕 用戶在前兩個框中輸入數字 點擊按鈕保證頁面不刷新的狀況下將數據發到後端作計算 將計算好的結果再發給前端展現到第三個input框中
效果:瀏覽器
def index(request): if request.method == 'POST': i1 = request.POST.get('i1') i2 = request.POST.get('i2') # i1 和 i2 是字符串類型 須要先作類型轉換 i3 = int(i1) + int(i2) return HttpResponse(i3) return render(request,'index.html')
ajax基本語法結構 // ajax基本語法 $.ajax({ // 1.到底朝哪一個後端提交數據 url:'', // 控制數據的提交路徑 有三種寫法 跟form表單的action屬性一致 type:'post', // 2.指定當前請求方式 data:{'i1':$('#i1').val(),'i2':$('#i2').val()}, // 3.提交的數據 // 4.ajax是異步提交 因此須要給一個回調函數來處理返回的結果 success:function (data) { // data就是異步提交的返回結果 // 將異步回調的結果經過DOM操做渲染到第三個input框中 $('#i3').val(data) } })
urlencoded formdata application/json
form表單默認是urlencoded編碼格式傳輸數據 urlencoded數據格式: username=jason&password=123 django後端針對該格式的數據 會自動解析並幫你打包到request.POST中 formdata數據格式: django後端針對符合urlencoded編碼格式數據(普通鍵值對)仍是統一解析到request.POST中 而針對formdata文件數據就會自動解析放到request.FILES中 application/json django後端針對json格式數據 並不會作任何的處理 而是直接放在request.body中
ajax默認的也是urlencoded編碼格式 先後端數據交互 編碼格式與數據格式必定要一致 不能騙人家!!! ,聲明什麼編碼格式,就用傳什麼格式
$('#d2').on('click',function () { $.ajax({ url:'', type:'post', contentType:'application/json', // 修改content-Type參數 data:JSON.stringify({'username':'jason','password':123}), // 將數據序列化成json格式字符串 success:function (data) { alert(data) } }) })
前端不會處理json格式的數據,而是直接塞進request.body中。咱們本身處理json格式數據,拿到的是二進制json
咱們本身處理,解碼,反序列化
json.loads可以自動解碼而且序列化
def ab_ct(request): if request.method == 'POST': # 本身處理json格式數據 json_bytes = request.body # 擴展 json.loads可以自動解碼並序列化 json_dict = json.loads(json_bytes) print(json_dict,type(json_dict)) print(request.POST) print(request.FILES) return render(request,'ab_ct.html')
須要藉助內置對象FormData
這個對象能夠傳普通鍵值對,也能夠傳文件
jQ new關鍵字生成對象
ajax發送文件(******) 內置對象FormData 即發普通鍵值對也發文件 // ajax發送文件數據 須要藉助於內置對象 $('#d3').click(function () { // 1 須要先生成一個內置對象 var myFormData = new FormData(); // 2 傳普通鍵值對 當普通鍵值對較多的時候 咱們能夠利用for循環來添加 myFormData.append('username','jason'); myFormData.append('password',123); // 3 傳文件 myFormData.append('myfile',$('#i1')[0].files[0]); // 獲取input框內部用戶上傳的文件對象 // 發送ajax請求 $.ajax({ url:'', type:'post', data:myFormData, // 發送formdata對象須要指定兩個關鍵性的參數 processData:false, // 讓瀏覽器不要對你的數據進行任何的操做 contentType:false, // 不要使用任何編碼格式 對象formdata自帶編碼格式而且django可以識別該對象 success:function (data) { alert(data) } }) })
藉助serializers幫你自動完成序列化
from app01 import models from django.core import serializers def ab_se(request): user_queryset = models.Userinfo.objects.all() user_list = [] for user_obj in user_queryset: user_list.append({ 'username':user_obj.username, 'password':user_obj.password, 'gender':user_obj.get_gender_display(), }) res = json.dumps(user_list) res = serializers.serialize('json',user_queryset) # 序列化 return HttpResponse(res)
須要大家掌握的僅僅是如何使用便可 推導思路能夠稍做了解 後端 current_page = request.GET.get('page', 1) all_count = book_queryset.count() # 1 現生成一個自定義分頁器類對象 page_obj = Pagination(current_page=current_page,all_count=all_count,pager_count=9) # 2 針對真實的queryset數據進行切片操做 page_queryset = book_queryset[page_obj.start:page_obj.end] return render(request,'ab_bc.html',locals()) 前端 {% for book_obj in page_queryset %} <p>{{ book_obj.title }}</p> {% endfor %} {{ page_obj.page_html|safe }}
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: 最多顯示的頁碼個數 用法: queryset = model.objects.all() page_obj = Pagination(current_page,all_count) page_data = queryset[page_obj.start:page_obj.end] 獲取數據用page_data而再也不使用原始的queryset 獲取前端分頁樣式用page_obj.page_html """ 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(''' </nav> </ul> ''') return ''.join(page_html_list)