BBS專案分佈搭建五(評論相關功能實現)
阿新 • • 發佈:2022-03-18
BBS專案分佈搭建五(評論相關)
1. 根評論邏輯實現
# 在models.py檔案中 修改: # 7. 評論表 parent = models.ForeignKey(to='self', null=True) # 新增路由(最好放在文章詳情之上): # 評論功能 url(r'^comment/', views.comment), # 在views.py中 新增功能: # 10. 評論功能 def comment(request): if request.is_ajax() and request.method == 'POST': back_dic = {'status': 200, 'msg': '評論成功'} # 1. 接收引數 content = request.POST.get('content') article_id = request.POST.get('article_id') # 2. 驗證引數 if not content: back_dic['status'] = 1013 back_dic['msg'] = '評論內容不能為空哦~' return JsonResponse(back_dic) if not article_id: back_dic['status'] = 1014 back_dic['msg'] = '評論的文章不存在' return JsonResponse(back_dic) # 3. 驗證是否登入,驗證儘量的完善 if not request.session.get('username'): back_dic['status'] = 1015 back_dic['msg'] = '請先登入在評論' return JsonResponse(back_dic) # 4. 處理評論邏輯 # 4.1 操作評論表,文章表(評論數) # 3.2 事務:保證資料安全,ACID四大特性,原子性,保證的是同一個事務中的SQL必須同時成功,同時失敗 # 3.3 在企業中,遇到跟財務相關的需求,儘量都要使用事務 from django.db import transaction with transaction.atomic(): models.Article.objects.filter(pk=article_id).update(comment_num=F('comment_num') + 1) models.Comment.objects.create( content=content, article_id=article_id, user_id=request.session.get('id'), ) return JsonResponse(back_dic) return HttpResponse('ok') # 修改article_detail.html檔案 # 在 {% block content %} 標籤中新增以下內容: {# 評論樣式開始#} {% if request.session.username %} <div > <p> <span class="glyphicon glyphicon-comment"></span>發表評論 </p> <p> <textarea name="" id="content" cols="30" rows="10"></textarea> </p> <p> <input type="button" class="btn btn-success commit" value="提交"> </p> </div> {% endif %} {# 評論樣式結束#} # 在 {% block js %} </script> 標籤中新增以下內容: // 提交評論 $(".commit").click(function () { // 先獲取評論內容 var content = $('#content').val(); var article_id = '{{ article_id }}'; // 拿到文章id比對 // 提交ajax $.ajax({ url: '/comment/', type: 'post', data: {'content': content, article_id: article_id, }, success: function (res) { console.log(res); } }) }) </script>
2. 評論內容前端列表樣式準備
# 修改article_detail.html檔案 # 在 {% block content %}標籤中新增: {# 評論列表開始#} <div class="comment"> <h1>評論列表</h1> <ul class="list-group"> <li class="list-group-item"> <span style="margin-right: 10px;color: #399ab2"># 1樓</span> <span style="margin-right: 10px">2022-03-08</span> <span style="color: #399ab2">吾 荒天帝</span> <span style="margin-right: 10px">{{ comment.create_time|date:'Y-m-d H:i' }}</span> <span style="color: #399ab2">{{ comment.user.username }}</span> <span><a href="" class="pull-right reply" style="text-decoration: none;">回覆</a></span> <p style="margin-top: 10px;margin-left: 15px;"> 一劍斷萬古! 他化自在,他化萬古! </p> </li> <li class="list-group-item"> <span style="margin-right: 10px;color: #399ab2"># 1樓</span> <span style="margin-right: 10px">2022-03-08</span> <span style="color: #399ab2">吾 荒天帝</span> <span style="margin-right: 10px">{{ comment.create_time|date:'Y-m-d H:i' }}</span> <span style="color: #399ab2">{{ comment.user.username }}</span> <span><a href="" class="pull-right reply" style="text-decoration: none;">回覆</a></span> <p style="margin-top: 10px;margin-left: 15px;"> 一劍斷萬古! 他化自在,他化萬古! </p> </li> <li class="list-group-item"> <span style="margin-right: 10px;color: #399ab2"># 1樓</span> <span style="margin-right: 10px">2022-03-08</span> <span style="color: #399ab2">吾 荒天帝</span> <span style="margin-right: 10px">{{ comment.create_time|date:'Y-m-d H:i' }}</span> <span style="color: #399ab2">{{ comment.user.username }}</span> <span><a href="" class="pull-right reply" style="text-decoration: none;">回覆</a></span> <p style="margin-top: 10px;margin-left: 15px;"> 一劍斷萬古! 他化自在,他化萬古! </p> </li> <li class="list-group-item"> <span style="margin-right: 10px;color: #399ab2"># 1樓</span> <span style="margin-right: 10px">2022-03-08</span> <span style="color: #399ab2">吾 荒天帝</span> <span style="margin-right: 10px">{{ comment.create_time|date:'Y-m-d H:i' }}</span> <span style="color: #399ab2">{{ comment.user.username }}</span> <span><a href="" class="pull-right reply" style="text-decoration: none;">回覆</a></span> <p style="margin-top: 10px;margin-left: 15px;"> 一劍斷萬古! 他化自在,他化萬古! </p> </li> <li class="list-group-item"> <span style="margin-right: 10px;color: #399ab2"># 1樓</span> <span style="margin-right: 10px">2022-03-08</span> <span style="color: #399ab2">吾 荒天帝</span> <span style="margin-right: 10px">{{ comment.create_time|date:'Y-m-d H:i' }}</span> <span style="color: #399ab2">{{ comment.user.username }}</span> <span><a href="" class="pull-right reply" style="text-decoration: none;">回覆</a></span> <p style="margin-top: 10px;margin-left: 15px;"> 一劍斷萬古! 他化自在,他化萬古! </p> </li> </ul> </div> {# 評論列表結束#} # 在 {% block css %} <style> 標籤中新增: .reply:hover { color: #9cba39; }
3. 評論後端邏輯實現
# 在views.py中 文章詳情頁功能中新增查詢評論內容: # 8. 文章詳情頁 # 查詢當前文章的所有評論 comment_list = models.Comment.objects.filter(article_id=article_id).all() return render(request, 'article_detail.html', locals()) # 修改article_detail.html檔案 # 修改 {% block js %} </script> 標籤內的 // 提交ajax: // 提交ajax $.ajax({ url: '/comment/', type: 'post', data: {'content': content, article_id: article_id, }, success: function (res) { console.log(res); var userName = '{{ request.session.username }}' if (res.status == 200) { // 1. 清空評論框 $("#content").val(''); // 2. 把評論成功的資訊放到頁面上 $("#error_msg").text(res.msg); // 3. 評論之後,渲染臨時評論 // ``反引號 引用模板語法 var html = ` <li class="list-group-item"> <span class="glyphicon glyphicon-comment"></span> <span style="color: #399ab2">${userName}</span> <p style=" margin-top: 10px;margin-left: 15px;"> ${content} </p> </li> `; {#// 使用字串引號也可以達到同樣效果#} {#var html = ""#} {#html += '<li class="list-group-item">' +#} {# '<span class="glyphicon glyphicon-comment"></span>'#} {# + '<span style="color: #399ab2">' + userName + '</span>' +#} {# '<p style=" margin-top: 10px;margin-left: 15px;">' + content + '</p>' +#} {# '</li>';#} $('.list-group').append(html); } } }) }) </script>
4. 子評論功能實現
# 在views.py中修改 評論功能 兩處:
# 10. 評論功能
# 1. 接收引數
content = request.POST.get('content')
article_id = request.POST.get('article_id')
parent_id = request.POST.get('parent_id') # 一處
with transaction.atomic():
models.Article.objects.filter(pk=article_id).update(comment_num=F('comment_num') + 1)
models.Comment.objects.create(
content=content,
article_id=article_id,
user_id=request.session.get('id'),
parent_id=parent_id # 二處
)
return JsonResponse(back_dic)
# 將 {# 評論列表開始#} 下面的 <span><a標籤的 href="" 刪除 達到阻止a標籤預設提交問題
此外 也可以在 // 子評論 下資料提交中進行阻止
# 修改 article_detail.html檔案:
# 修改 評論列表 內容:
{# 評論列表開始#}
<div class="comment">
<h1>評論列表</h1>
<ul class="list-group">
{% for comment in comment_list %}
<li class="list-group-item">
<span style="margin-right: 10px;color: #399ab2"># {{ forloop.counter }}樓</span>
<span style="margin-right: 10px">{{ comment.create_time|date:'Y-m-d H:i' }}</span>
<span style="color: #399ab2">{{ comment.user.username }}</span>
<span><a class="pull-right reply" style="text-decoration: none;" username="{{ comment.user.username }}" comment_id="{{ comment.pk }}">回覆</a></span>
<p style="margin-top: 10px;margin-left: 15px;">
{% if comment.parent_id %}
<span>@ {{ comment.parent.user.username }}</span>
<p>
{{ comment.content }}
</p>
{% else %}
{{ comment.content }}
{% endif %}
</p>
</li>
{% endfor %}
</ul>
</div>
{# 評論列表結束#}
# 修改 {% block js %} </script> 標籤內容:
{% block js %}
<script>
var parent_id = null; // 定義全域性變數,目的是,在提交評論的事件裡使用子評論事件裡的根評論id
$('.active').click(function () {
var is_up = $(this).hasClass('diggit'); // true false
var article_id = '{{ article_id }}';
var _this = $(this)
// 傳送ajax請求
$.ajax({
url: '/up_or_down/',
type: 'post',
data: {'is_up': is_up, article_id: article_id},
success: function (res) {
console.log(res);
if (res.status == 200) {
$('.error_msg').text(res.msg);
var old_num = Number(_this.children().text());
_this.children().text(old_num + 1)
} else if (res.status == 1010) {
$('.error_msg').append(res.msg)
} else {
layer.msg(res.msg)
}
}
})
})
// 提交評論
$(".commit").click(function () {
// 先獲取評論內容
var content = $('#content').val();
var article_id = '{{ article_id }}'; // 拿到文章id比對
// 重點:如何區分是根評論還是子評論
if (parent_id) {
// 子評論
var num = content.indexOf('\n') + 1;
content = content.slice(num) // 把換行符之前的內容全部切掉
}
// 提交ajax
$.ajax({
url: '/comment/',
type: 'post',
data: {'content': content, article_id: article_id, parent_id: parent_id},
success: function (res) {
console.log(res);
var userName = '{{ request.session.username }}'
if (res.status == 200) {
// 1. 清空評論框
$("#content").val('');
// 2. 把評論成功的資訊放到頁面上
$("#error_msg").text(res.msg);
// 3. 評論之後,渲染臨時評論 // ``反引號 引用模板語法
var html = `
<li class="list-group-item">
<span class="glyphicon glyphicon-comment"></span>
<span style="color: #399ab2">${userName}</span>
<p style=" margin-top: 10px;margin-left: 15px;">
${content}
</p>
</li>
`;
{#// 使用字串引號也可以達到同樣效果#}
{#var html = ""#}
{#html += '<li class="list-group-item">' +#}
{# '<span class="glyphicon glyphicon-comment"></span>'#}
{# + '<span style="color: #399ab2">' + userName + '</span>' +#}
{# '<p style=" margin-top: 10px;margin-left: 15px;">' + content + '</p>' +#}
{# '</li>';#}
$('.list-group').append(html);
// 根評論的id要清空
parent_id = null;
}
}
})
})
// 子評論
$('.reply').click(function (event) {
{#alert(123)#}
{#阻止a標籤預設提交問題其他方法#}
{#return false; // 阻止預設提交, 不僅適用於a標籤,還適用於form表單#}
{#event.preventDefault() // 阻止預設提交#}
// 子評論邏輯
var userName = $(this).attr('username');
// 獲取根評論的id
parent_id = $(this).attr('comment_id');
var s = '@' + userName + '\n'
$('#content').val(s).focus();
})
</script>
{% endblock %}