# 課程鏈接
全新 django3 入門到項目實戰(零基礎學django、項目開發實踐、大學畢業設計均可用)_哔哩哔哩_bilibili
# 課程內容
(1)5-5 訂單-ajax刪除(對話框)
(2)5-6 訂單-編輯
(3)5-7 訂單-對話框邏輯調整
(4)5-8 數據統計-柱狀圖
(5)5-9 數據統計-餅圖和折線圖
# 長風破浪會有時,直掛雲帆濟滄海
# (1)刪除功能(JS 的知識點!!!)
1)這裡有兩種方案來做,一種是我們點擊了某條數據的刪除鍵,那麼前端將選中的數據的 id 值取出來放在某個地方,當點擊確認刪除後,系統再將這個 id 發給後台進行刪除;還有一種就是定義一個全局變量,只要點擊了刪除,那麼對應的 id 就好賦值給這個全局變量,當確認刪除後,就將全局變量發給後台(這也是我們後面用的)。
由上面的方法二可知,我們定義了一個全局變量,那麼點擊了刪除鍵後,所選數據的 id 就會賦值給這個全局變量,然後確認刪除後,再將 id 值發送給後端。
2)前端代碼。那麼我們首先要對前端的編輯代碼添加一下特有的屬性,為了就是後續 js 能夠索引到它。這裡就只需要記住,不為什麼。 那麼特有屬性,就是 uid="{ {obj.id}}" ,相當於就是點擊的那條數據的 id 值,即為 uid。
3)然後我們綁定一個點擊事件,只要單擊了這個刪除按鈕,就把它的 id 賦值給我們設置的全局變量(因為我們遵循的是第二種方法來做)。當然了,還有刪除操作的點擊事件的方法函數 formDeleteEvent() 、確認刪除點擊事件的方法函數 confirmDeleteEvent() ,如圖所示。
4)首先我們來編寫 formDeleteEvent() 的函數。流程是這樣的,只要在某行點擊了刪除鍵,那麼模態對話框就會顯示出來,然後我們就將這行數據的 id 賦值給全局變量 DELETE_ID。那麼我們如何知道是哪一個標簽的呢,那就是使用 $(this) 方法,返回當前選中的標簽對象,同時調用 attr() 方法,來獲取 uid 的值。這種方式,我們只需要記住即可。
5)在彈出的模態對話框中,如果用戶確認了刪除,那麼我們就要將全局變量獲得的 uid 值,返回到後端,讓後端執行相應的刪除操作了。也就是調用我們的確認刪除點擊事件的方法函數 confirmDeleteEvent(),流程就是使用 ajax 將 uid 傳到後台。但是在此之前,我們需要給 tr 標簽也加一個 uid 屬性,方便後續的刪除操作。
6)確認刪除的第一種方法,就是要配合上面的 tr 標簽的屬性來用。直接給出代碼。格式可能有點不好看,但是這個方法比較麻煩,詳細的注釋在下面了。這個主要是拿來學習下 js 的用法而已。
function confirmDeleteEvent() { $("#confirmDelete").click(function () { $.ajax({ //其實是可以直接做字符串拼接的,如"/order/"+ DELETE_ID + "/delete/", //那麼我們可以更簡單點,如下: url: '/order/delete/', type: 'GET', //因為我們用的是 GET 請求,所以請求的時候,會將 url 自動拼接為: // 設 DELETE_ID=123,那麼發送的時候是 /order/delete/?uid=123 data: { uid: DELETE_ID }, dataType: 'JSON', success: function (res) { if (res.status) { alert("刪除成功"); $("#deleteModal").modal('hide'); /** 在頁面中刪除掉被刪除的那行數據(之前只是在數據庫中刪除了) * $("tr") 索引的就是頁面中的 tr 標簽。然後我們索引具有刪除 uid 的那個 tr 標簽,執行刪除操作, * 這裡的$("tr[uid='" + DELETE_ID + "']") 是字符串拼接,其中 DELETE_ID 會自動轉為 str 類型 * 設 Str1: "tr[uid='" * Str2: DELETE_ID * Str3: "']" , 那麼上面的式子就是 $(Str1 + Str2 + Str3) * 刪除的話就是執行 remove() 方法。即 * $("tr[uid='" + DELETE_ID + "']").remove(); * 【注意】 * 但是這種方法,存在問題。如果有分頁數據,且執行刪除後, * 後面頁的數據可能沒辦法頂到當前頁 */ $("tr[uid='" + DELETE_ID + "']").remove(); //全局變量置空 DELETE_ID = 0; }else{ //返回錯誤信息 alert(res.error) } } }) }) }
7)確認刪除的方法二,這個是很簡單的,就是我們執行刪除,並且隱藏模態對話框後,直接自動刷新頁面即可。
# (1)索引 id(這是初級寫法)
1)其實編輯的索引 id 的邏輯是和刪除的索引 id 邏輯是一樣的。一樣的設置特有屬性,和 js 代碼,這裡我們直接上代碼。
2)js 代碼。基本邏輯就是,每次點擊事件後,先清空原來模態對話框的數據,不然不同的數據間會沖突。找到選中的 id 值,然後通過 ajax 請求發送 id 值到後台,後台再將原始的數據傳回前台,然後放入模態對話框,最後呈現給用戶查閱。
function bindEditEvent(){ $(".btn-edit").click(function (){ //清空原來 input 的數據 $("#formAdd")[0].reset(); //找到選中的那行數據的 id DELETE_ID = $(this).attr("uid") //ajax 的請求 $.ajax({ url: '/order/edit/', type: 'GET', data: { uid: DELETE_ID }, dataType: "JSON", success: function (res){ if (res.status){ //循環返回的數據 $.each(res.data, function (name, key) { $("#id_" + name).val(key) }) }else{ alert("編輯錯誤") } } }) //改一下抬頭 $("#myModalLabel").text("編 輯"); //顯示模態對話框 $('#myModal').modal('show'); }) }
3)視圖函數的代碼如下,更詳細注釋見後面的圖示。
def order_edit(request): uid = request.GET.get("uid") """ 從數據庫中取數據,返回的類型: (1) row_object = models.Order.objects.filter(pk=uid).first(), # row_object 是一個對象。取數據的話,比如 title 屬性。 # 獲取數據可以 row_object.title 就是點屬性的方法。 # 但是這種查詢方式是返回對象,無法以 Json 格式為序列化數據返回。 (2) row_list = models.Order.objects.filter(pk=uid).values("title", "price", "status").first() # 還有一種方法。但其實也可以是使用 .values() 方法, # 這樣子返回的是一個字典,即 row_list = {'title': '電視', 'price': 1231232, 'status': 2} (3) row = models.Order.objects.all() # 返回的是一個對象查詢集合, 即 <QuerySet [<Order: Order object (4)>, ...], 每一個對象都是一條數據 # 可以通過 row[0].title 來第一條數據的屬性值 (4) row = models.Order.objects.all().values("title", "price") # 這裡我們指定了特定的值,那麼返回的就是一個字典查詢集合,即 [{}, {}, ...], 每一個 {} 是一條數據。 # 事實上輸出例如:<QuerySet [{'title': '手機', 'price': 12312}, {'title': '1231', 'price': 2131}, ...]> (5) row = models.Order.objects.all().values_list("title", "price") # 這裡返回的是元組查詢集。就是 [(), (), ...] , 每一個 () 是一條數據, # 裡面元素的個數取決於我們給的 values_list("a", "b", "c", ...) 括號裡面的字段個數。 # 比如我們只給了兩個屬性,那麼就是這樣的 <QuerySet [('手機', 12312), ('1231', 2131), ...] """ # 這裡我們用上面的第 (2) 種方法 row_list = models.Order.objects.filter(pk=uid).values("title", "price", "status").first() if not row_list: ret = { "code": 1002, "status": False } return JsonResponse(ret) # 查詢成功的話,返回相應的數據 ret = { "code": 1000, "status": True, "data": row_list } return JsonResponse(ret)
4)數據庫的查詢復習。
5)之所以說這個是因為 json 能返回的數據類型只能局限於基本的數據類型,如下圖所示。
# (1)完善流程。
1)如果按照上述的方法來做的話,我們點擊保存的時候,就會直接變成新建多一條數據。這是因為我們的新建和編輯的模態對話框是共用的。我們可以加入一個全局變量用來判斷,我們的操作是新建還是編輯。下面是 js 代碼,同時,我們要把編輯的事件的變量也給改了。【補充一下,如果一個變量為 undefined,那麼轉換為 boolean 類型的話,就是 False,基於這個思想來判斷是新建還是編輯】
2)以下是編輯部分的完整 js 代碼。
//修改後的代碼 function formAddEvent() { $("#btnSave").click(function () { $(".error-msg").empty() if (EDIT_ID) { //編輯 $.ajax({ url: '/order/edit/save/' + "?uid=" + EDIT_ID, type: "post", data: $("#formAdd").serialize(), dataType: "JSON", success: function (res) { if (res.status) { alert("編輯成功") //保存成功後,清空表單。 // 因為jQuery 沒有置空的功能,因此通過$("#formAdd")[0] 來綁定一個 DOM 對象 // 調用 .reset() 方法就可以將輸入框給置空了。 $("#formAdd")[0].reset(); //保存成功後自動關閉 $("#myModal").modal('hide'); //保存成功後,頁面自動刷新的方法。 location.reload(); } else { if (res.err_msg) { alert(res.err_msg) console.log(res.status) } else { $.each(res.error, function (name, err) { $("#id_" + name).next().text(err[0]) }) } } } }) } else { $.ajax({ url: '/order/add/', type: "post", data: $("#formAdd").serialize(), dataType: "JSON", success: function (res) { if (res.status) { alert("保存成功") //保存成功後,清空表單。 // 因為jQuery 沒有置空的功能,因此通過$("#formAdd")[0] 來綁定一個 DOM 對象 // 調用 .reset() 方法就可以將輸入框給置空了。 $("#formAdd")[0].reset(); //保存成功後自動關閉 $("#myModal").modal('hide'); //保存成功後,頁面自動刷新的方法。 location.reload(); } else { $.each(res.error, function (name, err) { {#console.log(name, err)#} $("#id_" + name).next().text(err[0]) }) } } }) } }) }
3)我們編輯保存的視圖函數如下:
# (1)畫圖的第三方庫
1)當前主要使用的畫圖庫有兩種,一個是國外的 highcharts,還有一個是國內 echarts,這節武sir 主要是以 echarts 為例講的。
2)echarts 的基本使用。打開鏈接:Handbook - Apache ECharts ,我們可以看到如下的界面,選擇通過 jsDelevr CDN 來下載。
使用 CDN 下載的時候,我們能來到如下界面,然後直接點紅框的下載。下載的是一個類似於 demo 的壓縮文件,我們只需要解壓找到 /dist/echarts.min.js 即可。然後講這個 js 文件放在我們 django 項目的 static/js/ 文件夾下即可。CDN 直通車:echarts CDN by jsDelivr - A CDN for npm and GitHub
3)然後我們直接就配置一個簡單的路由和前端頁面,來使用 echarts 官方給的示例代碼,繪制一個柱狀圖。當然在此之前我們需要做一個是具有 id = bar ,帶有長寬的 div 標簽。
顯示的結果如圖:
# (2)示例代碼的數據配置(本節主要是自己寫的)
這一節主要借助文檔來查閱和調試查看,我們只需要知道基本使用,後續根據需要到文檔中查閱即可,文檔鏈接: Documentation - Apache ECharts
1)title 的配置。 title 放的是一個字典(注意是 js 的),那格式就是 title: {}。比如下面的例子,我們給常用的一些屬性寫了備注。更多的可以參考文檔。
結果如下圖所示:
2)legend 的配置。這個是配置數據標識的。直接上代碼看:
那麼更直觀的就是,顯然 data 就是數據標識的名稱。
3)xAxis 就是表的橫軸,更多的可以查看文檔來使用。 yAxis 說的就是縱軸,這個基本都是查閱文檔來做
如圖所示:
4)series 就是放數據的,我們放了兩條數據進去。如下圖所示,
那麼最後的結果如下:
【總之,要用的時候,直接去查閱文檔】
# (3)請求數據的方式來繪制柱狀圖
1)模擬請求數據,然後自動繪制。首先是 js 的代碼。
<script type="text/javascript"> $(function () { paintBar(); }) function paintBar() { // 基於准備好的dom,初始化echarts實例 var myChart = echarts.init(document.getElementById('bar')); //bar 圖專用 var option = { color: [], title: {}, tooltip: {}, legend: { data: [], bottom: 0 }, xAxis: { data: [] }, yAxis: {}, series: [] } $.ajax({ url: '/charts/bar/', type: 'get', dataType: 'JSON', success: function (res) { if (res.status) { option.color = res.color; option.title = res.title option.legend.data = res.title.data option.xAxis.data = res.xAxis.data option.series = res.series //顯示 myChart.setOption(option); } }, }) } </script>
2)後端的視圖函數:
def charts_bar(request): ret = { "status": True, "color": ["#CC0033", "#3398DB"], "title": { "text": 'ECharts', "subtext": "子標題", "left": "20%", "textStyle": { "s": 30 } }, "legend": { "data": ['銷量', "啥也不是"], "bottom": "0%" }, "xAxis": { "data": ['襯衫', '羊毛衫', '雪紡衫', '褲子', '高跟鞋', '襪子'] }, "series": [ { "name": '銷量', "type": 'bar', "data": [5, 20, 36, 10, 10, 20] }, { "name": '啥也不是', "type": 'bar', "data": [5, 20, 36, 10, 10, 20] } ] } return JsonResponse(ret)
【總之,多看 echarts 的文檔,並且注意返回數據的格式。】
# 鏈接~~~有空再看了。主要是結合文檔一起學。
全新 django3 入門到項目實戰(零基礎學django、項目開發實踐、大學畢業設計均可用)_哔哩哔哩_bilibili