MTV與MVC模型
MTV與MVC都是模型,只不過MTV是django自己定義的,具體看一下他們的意思
MTV模型(django)
M:模型層(models.py)
T:templates文件夾
V:視圖層(views)
MVC模型
M:模型層
V:視圖層(views.py)
C:控制器(Controller) urls.py
總結:本質上django的MTV也是MVC
前后端傳輸數據編碼格式
首先,在我們不指定傳輸數據的時候,默認的contentType都是urlencoded
urlencoded
對應的數據格式:name=jason&password=555
后端獲取數據:request.POST
PS:django會將urlencded編碼的數據解析自動放到request.POST
formdata
form表單傳輸文件的編碼格式
后端獲取文件格式數據:request.FILES
后端獲取普通鍵值對數據:request.POST
application/json
form表單不支持,Ajax支持
Ajax發送json格式數據
需要注意的點
編碼與數據格式要一致
Ajax(重點掌握)
Ajax支持異步提交數據,局部刷新頁面,這種情況我們在好多頁面都會看到,那我們要如何做到呢?先來學習Ajax的基礎語法~~~記住四兄弟即可
提交的地址(url):控制數據的提交地址,不寫默認往當前位置提交
提交的方式(type):默認是get,要將get請求換成post
提交的數據(data):類似於字典的格式,字典具有一一標識的優點
回調函數(success):function(data){}data接收到的后端傳輸的數據
基本結構如下:
<script> //記得寫在html頁面的最下方或者是你寫在js里面,然后引入 $('綁定事件的id').click(function () { //給你要讓Ajax觸發的按鈕綁定一個事件 $.ajax({ //Ajax的固定寫法,在{}里面寫你的四兄弟 url:'在這里寫你的提交的路徑', //不寫默認是當前頁面提交 type:'post' , //將請求方式從默認的get改成post data:{}, //這個固定是data,后面放的是字典的形式 success:function (data) { //回調函數,拿到的是提交過后的數據,就是后端處理過后的數據,不要忘記參數,這個參數就是接收后端處理過后的數據 //對接受到的數據進行處理,做的是局部刷新操作
alert(123)
} }) }) </script>
自己嘗試着寫一個不跳轉的動態頁面,比如1+1=2
Ajax實現簡單版頁面局部刷新
我們首先需要的就是自己定義三個input框,然后動態獲取到前兩個框中的值,通過Ajax放到第三個input框中,代碼演示如下

<input type="text" id="i1" >+<input type="text" id="i2" >=<input type="text" id="i3"> <button id="b1">點我點我</button> <script> $('#b1').click(function () { $.ajax({ url:'/index/', type:'post', data:{'i1':$('#i1').val(),'i2':$('#i2').val()}, success:function (data) { $('#i3').val(data) } }) }) </script>
后端數據處理

def index(request): if request.method=='POST': i1=request.POST.get('i1') i2=request.POST.get('i2') print(i1,i2) res=int(i1)+int(i2) print(res,type(res)) return HttpResponse(res) return render(request,'index.html')
注意:Ajax不要與form表單聯合使用,直接使用input框就可以
Ajax實現json格式數據的傳輸
具體代碼展示如下

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css"> <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script> </head> <body> <p>username:<input type="text" id="u1"></p> <p>password:<input type="password" id="p1"></p> <button id="b1">提交</button> <input type="text" id="i1"> <script> $('#b1').click(function () { $.ajax({ url:'', type:'post', contentType:'application/json', data:JSON.stringify({ 'username':$('#u1').val(), 'password':$('#p1').val() }), success:function (data) { $('#i1').val(data) } }) }) </script> </body> </html>

def jsonajax(request): print('method:', request.method) print('POST:', request.POST) print('GET:', request.GET) print('body:', request.body) if request.method=='POST': data=request.body import json res=data.decode('utf-8') print(res,type(res)) res1=json.loads(res) print(res1,type(res1)) return HttpResponse(res1) return render(request,'jsonajax.html')
Ajax實現文件上傳
1.利用一個js內置對象FormData
2.這個FormData即可以傳普通的鍵值對也可以傳文件
3.需要修改兩個默認的參數processData,contentType
4.獲取input框存儲的文件數據$('input')[0].files[0]

def fileupload(request): if request.method=='POST': print(request.POST) print(request.FILES) return HttpResponse('收到了,小老弟') return render(request,'fileupload.html')

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css"> <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script> </head> <body> 文件上傳:<input type="file" id="i1"> <button id="b1">點擊提交</button> <script> $('#b1').click(function () { //傳文件的時候在form表單中我們需要制定參數是formdata,在這里我們也要來一個formdata let formdata = new FormData(); // formData對象不僅可以傳文件而且可以傳普通的鍵值對 formdata.append('name','jason'); //獲取input框存放的文件 //這里就用到了files這個方法,jquery是沒有這個方法的,所以我們要先得到一個js對象 //$('#i1')[0].files[0] 是因為files里面有好多個文件,而我們只要第一個 formdata.append('myfile',$('#i1')[0].files[0]); $.ajax({ url:'', type:'post', data:formdata, //ajax發送文件需要修改兩個固定的參數 processData:false, //告訴瀏覽器不要對數據進行處理 contentType:false, //告訴瀏覽器使用自帶的formdata格式,不要編碼 //回調函數 success:function (data) { alert(data) } }) }) </script> </body> </html>
總結:Ajax的特點是異步提交數據,產生局部刷新的效果,默認提交數據的方式是get提交,所以我們需要修改里面的type類型,然后我們還可以自定義FormData對象,Ajax也支持基於這個對象的大文件上傳。
Ajax和form表單的區別:
1.form表單不支持異步提交局部刷新
2.form表單不支持傳輸json格式數據
3.form表單與Ajax默認傳輸數據的編碼格式都是urlencoded
小結:基於現在所學,前端向后端發請求的方式有如下幾種
1.瀏覽器窗口手動輸入網址 get請求
2.a標簽的href屬性 get請求
3.form表單 get/post請求
4.Ajax get/post請求
其中,form表單和Ajax默認請求都是get
批量插入數據
當你打開一個頁面的時候,想要直接插入100條數據到數據庫,然后直接展示到前端頁面上來,如何做到?那還不簡單,我可以直接for循環100條數據,然后插入數據庫,最后在從數據庫中查出來展示,上代碼!
def insernum(request): #動態插入100條數據 for i in range(100): models.Num.objects.create(name='第%s本書'%i) #查詢所有的書籍展示到前端 book_list = models.Num.objects.all() return render(request,'num.html',locals())
但是,我們這樣子做到話,效果真的超級超級的低,前端頁面一直在等待我們數據的插入,雖然實現了數據的插入和展示,但是效率太低,那我們就得用到一個新的方法,我們先生成1000個數據對象,不走數據庫,速度是很快的,然后將這1000個數據對象一次性插入,django支持我們這么做,用的是bulk_creat(),批量插入數據,見代碼
def booklist(request): l=[] #數據太大的話,能不能做成生成器,每次只有一點**** for i in range(10000): l.append(models.Book2(name='第%s本書'%i)) 生成了一個對象 models.Book2.objects.bulk_create(l) 批量插入數據,速度超級快
g=(=models.Book2(name = '%s'%i)for i in range(100000000))***
models.Book2.objects.bulk_create(l)
自定義分頁器
首先我們要先導入一個類,這個類可以幫我們實現分頁的功能,將這個導入的文件放在utils里面,在下面新建一個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: 最多顯示的頁碼個數 用法: 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)
然后我們直接導入使用就可以了
后端: book_list = models.Book2.objects.all() # 數據總條數 all_count = book_list.count() # 當前頁 current_page = request.GET.get('page',1) # 實例一個分頁器對象 page_obj = my_page.Pagination(current_page=current_page,all_count=all_count) # 對總數據進行切片 page_queryset = book_list[page_obj.start:page_obj.end] 前端:
1.將book_list全部替換冊灰姑娘book_queryset
2.渲染分頁器樣式
{{ page_obj.page_html|safe }} # 幫你渲染的是帶有bootstrap樣式的分頁器
django 自帶的分頁器,和我們差不多,就相當於每次手動寫一遍
又是一個愉快的周末🙂🙂🙂