# url設計 /username/article/1 # 先驗證url是否會被其餘url頂替 # 文章詳情頁和我的站點基本一致 因此用模版繼承 # 側邊欄的渲染須要傳輸數據才能渲染 而且該側邊欄在不少頁面都須要使用 1.哪一個地方用就拷貝須要的代碼(不推薦 有點繁瑣) 2.將側邊欄製做成inclusion_tag """ 步驟 1.在應用下建立一個名字必須叫templatetags文件夾 2.在該文件夾內建立一個任意名稱的py文件 3.在該py文件內先固定寫兩行代碼 from django import template register = template.Library() # 自定義過濾器 # 自定義標籤 # 自定義inclusion_tag """ # 自定義inclusion_tag @register.inclusion_tag('left_menu.html') def left_menu(username): # 構造側邊欄須要的數據 user_obj = models.UserInfo.objects.filter(username=username).first() blog = user_obj.blog # 1 查詢當前用戶全部的分類及分類下的文章數 category_list = models.Category.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values_list( 'name', 'count_num', 'pk') # print(category_list) # <QuerySet [('jason的分類一', 2), ('jason的分類二', 1), ('jason的分類三', 1)]> # 2 查詢當前用戶全部的標籤及標籤下的文章數 tag_list = models.Tag.objects.filter(blog=blog).annotate(count_num=Count('article__pk')).values_list('name', 'count_num', 'pk') # print(tag_list) # <QuerySet [('tank的標籤一', 1), ('tank的標籤二', 1), ('tank的標籤三', 2)]> # 3 按照年月統計全部的文章 date_list = models.Article.objects.filter(blog=blog).annotate(month=TruncMonth('create_time')).values( 'month').annotate(count_num=Count('pk')).values_list('month', 'count_num') # print(date_list) return locals()
""" 瀏覽器上你看到的花裏胡哨的頁面,內部都是HTML(前端)代碼 那如今咱們的文章內容應該寫什麼??? >>> html代碼 如何拷貝文章 copy outerhtml 1.拷貝文章 2.拷貝點贊點踩 1.拷貝前端點贊點踩圖標 只拷了html 2.css也要拷貝 因爲有圖片防盜鏈的問題 因此將圖片直接下載到本地 課下思考: 前端如何區分用戶是點了贊仍是點了踩 1.給標籤各自綁定一個事件 兩個標籤對應的代碼其實基本同樣,僅僅是是否點贊點踩這一個參數不同而已 2.二合一 給兩個標籤綁定一個事件 // 給全部的action類綁定事件 $('.action').click(function () { alert($(this).hasClass('diggit')) }) 因爲點贊點踩內部有必定的業務邏輯,因此後端單獨開設視圖函數處理 """ # 我的建議:寫代碼先把全部正確的邏輯寫完再去考慮錯誤的邏輯 不要試圖二者兼得 import json from django.db.models import F def up_or_down(request): """ 1.校驗用戶是否登錄 2.判斷當前文章是不是當前用戶本身寫的(本身不能點本身的文章) 3.當前用戶是否已經給當前文章點過了 4.操做數據庫了 :param request: :return: """ if request.is_ajax(): back_dic = {'code':1000,'msg':''} # 1 先判斷當前用戶是否登錄 if request.user.is_authenticated(): article_id = request.POST.get('article_id') is_up = request.POST.get('is_up') # print(is_up,type(is_up)) # true <class 'str'> is_up = json.loads(is_up) # 記得轉換 # print(is_up, type(is_up)) # True <class 'bool'> # 2 判斷當前文章是不是當前用戶本身寫的 根據文章id查詢文章對象 根據文章對象查做者 根request.user比對 article_obj = models.Article.objects.filter(pk=article_id).first() if not article_obj.blog.userinfo == request.user: # 3 校驗當前用戶是否已經點了 哪一個地方記錄了用戶到底點沒點 is_click = models.UpAndDown.objects.filter(user=request.user,article=article_obj) if not is_click: # 4 操做數據庫 記錄數據 要同步操做普通字段 # 判斷當前用戶點了贊仍是踩 從而決定給哪一個字段加一 if is_up: # 給點贊數加一 models.Article.objects.filter(pk=article_id).update(up_num = F('up_num') + 1) back_dic['msg'] = '點同意功' else: # 給點踩數加一 models.Article.objects.filter(pk=article_id).update(down_num=F('down_num') + 1) back_dic['msg'] = '點踩成功' # 操做點贊點踩表 models.UpAndDown.objects.create(user=request.user,article=article_obj,is_up=is_up) else: back_dic['code'] = 1001 back_dic['msg'] = '你已經點過了,不能再點了' # 這裏你能夠作的更加的詳細 提示用戶到底點了贊仍是點了踩 else: back_dic['code'] = 1002 back_dic['msg'] = '你個臭不要臉的!' else: back_dic['code'] = 1003 back_dic['msg'] = '請先<a href="/login/">登錄</a>' return JsonResponse(back_dic) <script> // 給全部的action類綁定事件 $('.action').click(function () { {#alert($(this).hasClass('diggit'))#} let isUp = $(this).hasClass('diggit'); let $div = $(this); // 朝後端發送ajax請求 $.ajax({ url:'/up_or_down/', type:'post', data:{ 'article_id':'{{ article_obj.pk }}', 'is_up':isUp, 'csrfmiddlewaretoken':'{{ csrf_token }}' }, success:function (args) { if(args.code == 1000){ $('#digg_tips').text(args.msg) // 將前端的數字加一 // 先獲取到以前的數字 let oldNum = $div.children().text(); // 文本 是字符類型 // 易錯點 $div.children().text(Number(oldNum) + 1) // 字符串拼接了 1+1 = 11 11 + 1 = 111 }else{ $('#digg_tips').html(args.msg) } } }) }) </script>
""" 咱們先寫根評論 再寫子評論 點擊評論按鈕須要將評論框裏面的內容清空 根評論有兩步渲染方式 1.DOM臨時渲染 2.頁面刷新render渲染 子評論 點擊回覆按鈕發生了幾件事 1.評論框自動聚焦 2.將回覆按鈕所在的那一行評論人的姓名 @username 3.評論框內部自動換行 根評論子評論都是點擊一個按鈕朝後端提交數據的 parent_id 根評論子評論區別在哪? parent_id """