一、点赞和踩灭
样式
先来做样式,修改article_detail.html,增加div_digg的div
{% extends "base.html" %}{% block content %}
<div class="article_info">
<h4 class="text-center">{{ article_obj.title }}</h4>
<div class="content">
{{ article_obj.content|safe }}
</div>
<div id="div_digg">
<div class="diggit">
<span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
</div>
<div class="buryit">
<span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
</div>
</div>
</div>{% endblock %}
在static-->css目录下,创建文件article_detail.css
#div_digg { float: right; margin-bottom: 10px; margin-right: 30px; font-size: 12px; 125px; text-align: center; margin-top: 10px; }.diggit {
float: left;
46px;
height: 52px;
background: url("/static/img/upup.gif") no-repeat;
text-align: center;
cursor: pointer;
margin-top: 2px;
padding-top: 5px;
}.buryit {
float: right;
margin-left: 20px;
46px;
height: 52px;
background: url("/static/img/downdown.gif") no-repeat;
text-align: center;
cursor: pointer;
margin-top: 2px;
padding-top: 5px;
}
从博客园拷贝2个图片到static-->img目录下
修改base.html,引入article_detail.css
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="shortcut icon" href="https://common.cnblogs.com/favicon.ico" type="image/x-icon"/> {#公共样式#} <link rel="stylesheet" href="/static/css/theme/common.css"> {#个人站点主题样式#} <link rel="stylesheet" href="/static/css/theme/{{ blog.theme }}"> {#bootstrap#} <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css"> <script src="/static/js/jquery.js"></script> <script src="/static/bootstrap/js/bootstrap.js"></script> {#文章详情#} <link rel="stylesheet" href="/static/css/article_detail.css"></head>
<body>
<div class="header">
<p class="title">{{ blog.title }}</p>
</div><div class="container-fluid">
<div class="row">
<div class="col-md-3">
{#加载自定义标签模块#}
{% load my_tags %}
{#调用get_query_data标签,它返回left_region.html,是已经被渲染过的文件#}
{% get_query_data username %}
</div>
<div class="col-md-9">{</span>% block content %<span style="color: #000000;">} {</span>% endblock %<span style="color: #000000;">} </span></div> </div>
</div>
</body>
</html>
点击一篇文章:http://127.0.0.1:8000/xiao/articles/5/
拉到最下面,右侧效果如下:
绑定事件
推荐和反对有2个按钮,要绑定2个事件吗?答案是可以,但是不推荐使用!为什么呢?
因为会造成大量代码重复!这2个按钮需要发送的文章id和用户id是一样的,唯一不同的就是:一个是推荐,一个是反对。
修改article_detail.html增加div,测试js代码
注意:在base.html中已经导入了jquery
hasClass() 方法检查被选元素是否包含指定的 class。它返回True和False
{% extends "base.html" %}{% block content %}
<div class="article_info">
<h4 class="text-center">{{ article_obj.title }}</h4>
<div class="content">
{{ article_obj.content|safe }}
</div>
<div id="div_digg">
<div class="diggit action">
<span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
</div>
<div class="buryit action">
<span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
</div>
</div>
</div>
<script>
$(".action").click(function () {
{#hasClass() 方法检查被选元素是否包含指定的 class#}
var is_up = $(this).hasClass("diggit");
alert(is_up);}) </span></script><span style="color: #000000;">
{% endblock %}
刷新网页,点击文章右下角的推荐,提示true
点击反对,提示false
发送ajax请求
数据分析
到底是用get还是post呢?有一个规范:查询用get,更改用post
查看blog_articleupdown表,这个是点赞表。插入一条记录,需要3个参数,分别是是否点赞、文章id、用户id
注意:这个用户id是当前登录用户,不是文章作者!
由于在视图函数中,有一个全局变量request.user。它是用户登录之后,才有的!所以这个用户id,不需要传。
只需要传2个值就可以了,分别是是否点赞和文章id。
在article_detail.html中,已经有一个article_obj,它是一个model对象,那么就可以得到文章id。
是否点赞,通过js代码中的is_up变量,也可以知道。
所以发送的数据,不需要使用标签选择器来获取。直接使用即可!
操作流程
- 用户点击推荐或者反对,触发点击事件
- 发送ajax请求给服务器
- 服务器接收参数,生成一条点赞或者踩灭的记录
- 服务器将返回结果响应给浏览器,浏览器中的ajax代码的success中的data接收响应体
- ajax对响应的数据做判断,操作DOM,显示给用户看!
服务器处理
修改urls.py,增加一个路径digg
urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), path('index/', views.index), path('logout/', views.logout), path('', views.index), #点赞或者踩灭 path('digg/', views.digg),</span><span style="color: #008000;">#</span><span style="color: #008000;">文章详情</span> re_path(<span style="color: #800000;">'</span><span style="color: #800000;">(?P<username>w+)/articles/(?P<article_id>d+)/$</span><span style="color: #800000;">'</span><span style="color: #000000;">, views.article_detail), </span><span style="color: #008000;">#</span><span style="color: #008000;"> 跳转</span> re_path(<span style="color: #800000;">'</span><span style="color: #800000;">(?P<username>w+)/(?P<condition>category|tag|achrive)/(?P<params>.*)/$</span><span style="color: #800000;">'</span><span style="color: #000000;">, views.homesite), </span><span style="color: #008000;">#</span><span style="color: #008000;"> 个人站点</span> re_path(<span style="color: #800000;">'</span><span style="color: #800000;">(?P<username>w+)/$</span><span style="color: #800000;">'</span><span style="color: #000000;">, views.homesite),
]
注意:digg要放到文章详情的上面
修改article_detail.html
{% extends "base.html" %}{% block content %}
<div class="article_info">
<h4 class="text-center">{{ article_obj.title }}</h4>
<div class="content">
{{ article_obj.content|safe }}
</div>
<div id="div_digg">
<div class="diggit action">
<span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
</div>
<div class="buryit action">
<span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
</div>
</div>
</div>
{% csrf_token %}
<script>
$(".action").click(function () {
{#hasClass() 方法检查被选元素是否包含指定的 class#}
var is_up = $(this).hasClass("diggit");
{#判断是否登录#}
if ("{{ request.user.username }}") {
$.ajax({
url: "/digg/",
type: "post",
data: {
is_up: is_up,
article_id: "{{ article_obj.pk }}",
csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val()
},
success: function (data) {
console.log(data);
console.log(typeof data);} }) } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { location.href </span>= <span style="color: #800000;">"</span><span style="color: #800000;">/login/</span><span style="color: #800000;">"</span><span style="color: #000000;">; } }) </span></script><span style="color: #000000;">
{% endblock %}
修改views.py,增加视图函数digg
注意:导入2个模块
import json from django.http import JsonResponse
视图函数如下:
from django.shortcuts import render,HttpResponse,redirect from django.contrib import auth from blog.models import Article,UserInfo,Blog,Category,Tag,ArticleUpDown from django.db.models import Sum,Avg,Max,Min,Count from django.db.models import F import json from django.http import JsonResponse# Create your views here.
def login(request):</span><span style="color: #0000ff;">if</span> request.method==<span style="color: #800000;">"</span><span style="color: #800000;">POST</span><span style="color: #800000;">"</span><span style="color: #000000;">: user</span>=request.POST.get(<span style="color: #800000;">"</span><span style="color: #800000;">user</span><span style="color: #800000;">"</span><span style="color: #000000;">) pwd</span>=request.POST.get(<span style="color: #800000;">"</span><span style="color: #800000;">pwd</span><span style="color: #800000;">"</span><span style="color: #000000;">) </span><span style="color: #008000;">#</span><span style="color: #008000;"> 用户验证成功,返回user对象,否则返回None</span> user=auth.authenticate(username=user,password=<span style="color: #000000;">pwd) </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> user: </span><span style="color: #008000;">#</span><span style="color: #008000;"> 登录,注册session</span> <span style="color: #008000;">#</span><span style="color: #008000;"> 全局变量 request.user=当前登陆对象(session中)</span>
auth.login(request,user)
return redirect("/index/")</span><span style="color: #0000ff;">return</span> render(request,<span style="color: #800000;">"</span><span style="color: #800000;">login.html</span><span style="color: #800000;">"</span><span style="color: #000000;">)
def index(request):
article_list=Article.objects.all()
return render(request,"index.html",{"article_list":article_list})def logout(request): # 注销
auth.logout(request)
return redirect("/index/")def query_current_site(request,username): # 查询当前站点的博客标题
# 查询当前站点的用户对象
user = UserInfo.objects.filter(username=username).first()
if not user:
return render(request, "not_found.html")
# 查询当前站点对象
blog = user.blog
return blogdef homesite(request,username,**kwargs): # 个人站点主页
print("kwargs", kwargs)blog </span>=<span style="color: #000000;"> query_current_site(request,username) </span><span style="color: #008000;">#</span><span style="color: #008000;"> 查询当前用户发布的所有文章</span> <span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> kwargs: article_list </span>= Article.objects.filter(user__username=<span style="color: #000000;">username) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: condition </span>= kwargs.get(<span style="color: #800000;">"</span><span style="color: #800000;">condition</span><span style="color: #800000;">"</span><span style="color: #000000;">) params </span>= kwargs.get(<span style="color: #800000;">"</span><span style="color: #800000;">params</span><span style="color: #800000;">"</span><span style="color: #000000;">) </span><span style="color: #008000;">#</span><span style="color: #008000;">判断分类、随笔、归档</span> <span style="color: #0000ff;">if</span> condition == <span style="color: #800000;">"</span><span style="color: #800000;">category</span><span style="color: #800000;">"</span><span style="color: #000000;">: article_list </span>= Article.objects.filter(user__username=username).filter(category__title=<span style="color: #000000;">params) </span><span style="color: #0000ff;">elif</span> condition == <span style="color: #800000;">"</span><span style="color: #800000;">tag</span><span style="color: #800000;">"</span><span style="color: #000000;">: article_list </span>= Article.objects.filter(user__username=username).filter(tags__title=<span style="color: #000000;">params) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: year, month </span>= params.split(<span style="color: #800000;">"</span><span style="color: #800000;">/</span><span style="color: #800000;">"</span><span style="color: #000000;">) article_list </span>= Article.objects.filter(user__username=username).filter(create_time__year=<span style="color: #000000;">year, create_time__month</span>=<span style="color: #000000;">month) </span><span style="color: #0000ff;">return</span> render(request,<span style="color: #800000;">"</span><span style="color: #800000;">homesite.html</span><span style="color: #800000;">"</span>,{<span style="color: #800000;">"</span><span style="color: #800000;">blog</span><span style="color: #800000;">"</span>:blog,<span style="color: #800000;">"</span><span style="color: #800000;">username</span><span style="color: #800000;">"</span>:username,<span style="color: #800000;">"</span><span style="color: #800000;">article_list</span><span style="color: #800000;">"</span><span style="color: #000000;">:article_list})
def article_detail(request,username,article_id):
blog = query_current_site(request,username)</span><span style="color: #008000;">#</span><span style="color: #008000;">查询指定id的文章</span> article_obj = Article.objects.filter(pk=<span style="color: #000000;">article_id).first() user_id </span>= UserInfo.objects.filter(username=<span style="color: #000000;">username).first().nid </span><span style="color: #0000ff;">return</span> render(request,<span style="color: #800000;">'</span><span style="color: #800000;">article_detail.html</span><span style="color: #800000;">'</span>,{<span style="color: #800000;">"</span><span style="color: #800000;">blog</span><span style="color: #800000;">"</span>:blog,<span style="color: #800000;">"</span><span style="color: #800000;">username</span><span style="color: #800000;">"</span>:username,<span style="color: #800000;">'</span><span style="color: #800000;">article_obj</span><span style="color: #800000;">'</span>:article_obj,<span style="color: #800000;">"</span><span style="color: #800000;">user_id</span><span style="color: #800000;">"</span><span style="color: #000000;">:user_id})
def digg(request):
print(request.POST)
if request.method == "POST":
#ajax发送的过来的true和false是字符串,使用json反序列化得到布尔值
is_up = json.loads(request.POST.get("is_up"))
article_id = request.POST.get("article_id")
user_id = request.user.pkresponse </span>= {<span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span>: True, <span style="color: #800000;">"</span><span style="color: #800000;">msg</span><span style="color: #800000;">"</span>: None} <span style="color: #008000;">#</span><span style="color: #008000;"> 初始状态</span> <span style="color: #008000;">#</span><span style="color: #008000;">判断当前登录用户是否对这篇文章做过点赞或者踩灭操作</span> obj = ArticleUpDown.objects.filter(user_id=user_id, article_id=<span style="color: #000000;">article_id).first() </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> obj: response[</span><span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span>] = False <span style="color: #008000;">#</span><span style="color: #008000;"> 更改状态</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">: </span><span style="color: #008000;">#</span><span style="color: #008000;">插入一条记录</span> new_obj = ArticleUpDown.objects.create(user_id=user_id, article_id=article_id, is_up=<span style="color: #000000;">is_up) </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> JsonResponse(response) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">"</span><span style="color: #800000;">非法请求</span><span style="color: #800000;">"</span>)</pre>
json处理问题
ajax发送的过来的true和false是字符串,使用json反序列化得到布尔值
json支持7种数据格式,其中true和false是其中2种。那么反序列化之后,会得到一个布尔值。
为什么一定要反序列化呢?因为...create(...is_up=is_up) 等式右边的值,非空。那么ORM会认为是True!
所以不管ajax传过来的是true和falase,它都是字符串,那么ORM执行时,始终都是True
JsonResponse
JsonResponse对象是HttpRespon的子类,它主要和父类的区别在于:
1.它的默认Content-Type 被设置为: application/json
2.第一个参数,data应该是一个字典类型,如果不是字典,抛出 TypeError的异常
它返回json数据,那么ajax接收时,不需要反序列化,可以直接使用!
刷新网页,点击右侧的推荐,查看浏览器控制台
查看blog_articleupdown表记录,发现多了一条记录
查看Pycharm控制台输出:
<QueryDict: {'article_id': ['6'], 'csrfmiddlewaretoken': ['JgLyFpVgp92Rs8ppPCd2pm9jVj6z8bo9KSsMwKnakpB6CwTCT1K58v2JHLeR5ejN'], 'is_up': ['true']}>
判断用户之前的操作
当用户第一次点击推荐时,直接将数字加1。再次点击时,提示您已经推荐过!再次点击返回时,也提示您已经推荐过。
同理,当用户对一篇点击返回后。之后不论是点击推荐还是反对,都会提示您已经反对过!
不可以取消推荐或者反对!
修改views.py,获取上一次操作的记录
def digg(request): print(request.POST) if request.method == "POST": #ajax发送的过来的true和false是字符串,使用json反序列化得到布尔值 is_up = json.loads(request.POST.get("is_up")) article_id = request.POST.get("article_id") user_id = request.user.pkresponse </span>= {<span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span>: True, <span style="color: #800000;">"</span><span style="color: #800000;">msg</span><span style="color: #800000;">"</span>: None} <span style="color: #008000;">#</span><span style="color: #008000;"> 初始状态</span> <span style="color: #008000;">#</span><span style="color: #008000;">判断当前登录用户是否对这篇文章做过点赞或者踩灭操作</span> obj = ArticleUpDown.objects.filter(user_id=user_id, article_id=<span style="color: #000000;">article_id).first() </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> obj: response[</span><span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span>] = False <span style="color: #008000;">#</span><span style="color: #008000;"> 更改状态</span> response[<span style="color: #800000;">"</span><span style="color: #800000;">handled</span><span style="color: #800000;">"</span>] = obj.is_up <span style="color: #008000;">#</span><span style="color: #008000;"> 获取之前的操作,返回true或者false</span> <span style="color: #0000ff;">print</span><span style="color: #000000;">(obj.is_up) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: </span><span style="color: #008000;">#</span><span style="color: #008000;">插入一条记录</span> new_obj = ArticleUpDown.objects.create(user_id=user_id, article_id=article_id, is_up=<span style="color: #000000;">is_up) </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> JsonResponse(response) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">"</span><span style="color: #800000;">非法请求</span><span style="color: #800000;">"</span>)</pre>
修改article_detail.html的js代码
{% extends "base.html" %}{% block content %}
<div class="article_info">
<h4 class="text-center">{{ article_obj.title }}</h4>
<div class="content">
{{ article_obj.content|safe }}
</div>
<div id="div_digg">
<div class="diggit action">
<span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
</div>
<div class="buryit action">
<span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
</div>
</div>
</div>
{% csrf_token %}
<script>
$(".action").click(function () {
{#hasClass() 方法检查被选元素是否包含指定的 class#}
var is_up = $(this).hasClass("diggit");
{#判断是否登录#}
if ("{{ request.user.username }}") {
$.ajax({
url: "/digg/",
type: "post",
data: {
is_up: is_up,
article_id: "{{ article_obj.pk }}",
csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val()
},
success: function (data) {
console.log(data);
console.log(typeof data);
if (data.state) {
//提交成功
} else {
if (data.handled) { //判断之前的操作记录
$("#digg_tips").html("您已经推荐过!")
} else {
$("#digg_tips").html("您已经反对过!")
}
}} }) } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { location.href </span>= <span style="color: #800000;">"</span><span style="color: #800000;">/login/</span><span style="color: #800000;">"</span><span style="color: #000000;">; } }) </span></script><span style="color: #000000;">
{% endblock %}
修改static-->css目录下的article_detail.css,增加样式
#div_digg { float: right; margin-bottom: 10px; margin-right: 30px; font-size: 12px; 125px; text-align: center; margin-top: 10px; }.diggit {
float: left;
46px;
height: 52px;
background: url("/static/img/upup.gif") no-repeat;
text-align: center;
cursor: pointer;
margin-top: 2px;
padding-top: 5px;
}.buryit {
float: right;
margin-left: 20px;
46px;
height: 52px;
background: url("/static/img/downdown.gif") no-repeat;
text-align: center;
cursor: pointer;
margin-top: 2px;
padding-top: 5px;
}
.clear {
clear: both;
}#digg_tips{
color: red;
}
重启django项目,页面强制刷新几次!
再次点击,提示已经点过了
修改article_detail.html的js代码,增加动态效果,1秒后,清空红色文字
{% extends "base.html" %}{% block content %}
<div class="article_info">
<h4 class="text-center">{{ article_obj.title }}</h4>
<div class="content">
{{ article_obj.content|safe }}
</div>
<div id="div_digg">
<div class="diggit action">
<span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
</div>
<div class="buryit action">
<span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
</div>
</div>
</div>
{% csrf_token %}
<script>
$(".action").click(function () {
{#hasClass() 方法检查被选元素是否包含指定的 class#}
var is_up = $(this).hasClass("diggit");
{#判断是否登录#}
if ("{{ request.user.username }}") {
$.ajax({
url: "/digg/",
type: "post",
data: {
is_up: is_up,
article_id: "{{ article_obj.pk }}",
csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val()
},
success: function (data) {
console.log(data);
console.log(typeof data);
if (data.state) {
//提交成功
} else {
if (data.handled) { //判断之前的操作记录
$("#digg_tips").html("您已经推荐过!")
} else {
$("#digg_tips").html("您已经反对过!")
}
setTimeout(function () {
$("#digg_tips").html("") //清空提示文字
}, 1000)
}} }) } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { location.href </span>= <span style="color: #800000;">"</span><span style="color: #800000;">/login/</span><span style="color: #800000;">"</span><span style="color: #000000;">; } }) </span></script><span style="color: #000000;">
{% endblock %}
效果如下:
更新文章表
blog_articleupdown表有一个联合唯一索引,即使重复点击,也不会增加记录!
blog_article表有一个up_count和down_count字段,分别表示推荐和反对的计数。
那么这2个字段,也需要同时更新。在原有数值的基础上加1,需要使用F查询!
导入F模块,完整代码如下:
def digg(request): print(request.POST) if request.method == "POST": #ajax发送的过来的true和false是字符串,使用json反序列化得到布尔值 is_up = json.loads(request.POST.get("is_up")) article_id = request.POST.get("article_id") user_id = request.user.pkresponse </span>= {<span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span>: True, <span style="color: #800000;">"</span><span style="color: #800000;">msg</span><span style="color: #800000;">"</span>: None} <span style="color: #008000;">#</span><span style="color: #008000;"> 初始状态</span> <span style="color: #008000;">#</span><span style="color: #008000;">判断当前登录用户是否对这篇文章做过点赞或者踩灭操作</span> obj = ArticleUpDown.objects.filter(user_id=user_id, article_id=<span style="color: #000000;">article_id).first() </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> obj: response[</span><span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span>] = False <span style="color: #008000;">#</span><span style="color: #008000;"> 更改状态</span> response[<span style="color: #800000;">"</span><span style="color: #800000;">handled</span><span style="color: #800000;">"</span>] = obj.is_up <span style="color: #008000;">#</span><span style="color: #008000;"> 获取之前的操作,返回true或者false</span> <span style="color: #0000ff;">print</span><span style="color: #000000;">(obj.is_up) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: </span><span style="color: #008000;">#</span><span style="color: #008000;">插入一条记录</span> new_obj = ArticleUpDown.objects.create(user_id=user_id, article_id=article_id, is_up=<span style="color: #000000;">is_up) </span><span style="color: #0000ff;">if</span> is_up: <span style="color: #008000;">#</span><span style="color: #008000;"> 判断为推荐</span> Article.objects.filter(pk=article_id).update(up_count=F(<span style="color: #800000;">"</span><span style="color: #800000;">up_count</span><span style="color: #800000;">"</span>)+1<span style="color: #000000;">) </span><span style="color: #0000ff;">else</span>: <span style="color: #008000;">#</span><span style="color: #008000;"> 反对</span> Article.objects.filter(pk=article_id).update(down_count=F(<span style="color: #800000;">"</span><span style="color: #800000;">down_count</span><span style="color: #800000;">"</span>)+1<span style="color: #000000;">) </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> JsonResponse(response) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">"</span><span style="color: #800000;">非法请求</span><span style="color: #800000;">"</span>)</pre>
清空blog_articleupdown表记录
访问网页,重新点击。再次刷新页面,那么值就会更新了!
网页实时展示
上面已经实现了,点击之后,更新数据库。但是需要刷新网页,才会有效果。想要用户能实时看到数字,需要进行DOM操作。
获取网页原有的值,进行加1。最后进行DOM操作,展示给用户看!
修改article_detail.html的js代码
注意:js是弱类型语言,获取到值时,不能直接进行加法,需要强制转换才行!
{% extends "base.html" %}{% block content %}
<div class="article_info">
<h4 class="text-center">{{ article_obj.title }}</h4>
<div class="content">
{{ article_obj.content|safe }}
</div>
<div id="div_digg">
<div class="diggit action">
<span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
</div>
<div class="buryit action">
<span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
</div>
</div>
</div>
{% csrf_token %}
<script>
$(".action").click(function () {
{#hasClass() 方法检查被选元素是否包含指定的 class#}
var is_up = $(this).hasClass("diggit");
{#获取提示的span标签#}
var _this= $(this).children("span");
{#判断是否登录#}
if ("{{ request.user.username }}") {
$.ajax({
url: "/digg/",
type: "post",
data: {
is_up: is_up,
article_id: "{{ article_obj.pk }}",
csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val()
},
success: function (data) {
console.log(data);
console.log(typeof data);
if (data.state) {
//提交成功
var val=_this.text(); //获取text值
//在原有的基础上加1。注意:一定要进行类型转换
_this.text(parseInt(val)+1)
} else {
if (data.handled) { //判断之前的操作记录
$("#digg_tips").html("您已经推荐过!")
} else {
$("#digg_tips").html("您已经反对过!")
}
setTimeout(function () {
$("#digg_tips").html("") //清空提示文字
}, 1000)
}} }) } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { location.href </span>= <span style="color: #800000;">"</span><span style="color: #800000;">/login/</span><span style="color: #800000;">"</span><span style="color: #000000;">; } }) </span></script><span style="color: #000000;">
{% endblock %}
清空blog_articleupdown表记录
将blog_article表的相关字段设置为0
访问网页,重新点击,效果如下:
优化js代码
将if判断部分,改成三元运算
{% extends "base.html" %}{% block content %}
<div class="article_info">
<h4 class="text-center">{{ article_obj.title }}</h4>
<div class="content">
{{ article_obj.content|safe }}
</div>
<div id="div_digg">
<div class="diggit action">
<span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
</div>
<div class="buryit action">
<span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
</div>
</div>
</div>
{% csrf_token %}
<script>
$(".action").click(function () {
{#hasClass() 方法检查被选元素是否包含指定的 class#}
var is_up = $(this).hasClass("diggit");
{#获取提示的span标签#}
var _this = $(this).children("span");
{#判断是否登录#}
if ("{{ request.user.username }}") {
$.ajax({
url: "/digg/",
type: "post",
data: {
is_up: is_up,
article_id: "{{ article_obj.pk }}",
csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val()
},
success: function (data) {
console.log(data);
console.log(typeof data);
if (data.state) {
//提交成功
var val = _this.text(); //获取text值
//在原有的基础上加1。注意:一定要进行类型转换
_this.text(parseInt(val) + 1)
} else {
// 重复提交
var val = data.handled ? "您已经推荐过!" : "您已经反对过!";
$("#digg_tips").html(val);
setTimeout(function () {
$("#digg_tips").html("") //清空提示文字
}, 1000)
}} }) } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { location.href </span>= <span style="color: #800000;">"</span><span style="color: #800000;">/login/</span><span style="color: #800000;">"</span><span style="color: #000000;">; } }) </span></script><span style="color: #000000;">
{% endblock %}
事务
是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。
在上面的例子,点赞时,需要更新2个表。一个是blog_articleupdown表,一个是blog_article表。
如果有一个表没有更新,那么就会产生脏数据!为了避免这个问题,需要使用事务!
举例:模拟异常情况
修改digg视图函数,模拟异常
def digg(request): print(request.POST) if request.method == "POST": #ajax发送的过来的true和false是字符串,使用json反序列化得到布尔值 is_up = json.loads(request.POST.get("is_up")) article_id = request.POST.get("article_id") user_id = request.user.pkresponse </span>= {<span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span>: True, <span style="color: #800000;">"</span><span style="color: #800000;">msg</span><span style="color: #800000;">"</span>: None} <span style="color: #008000;">#</span><span style="color: #008000;"> 初始状态</span> <span style="color: #008000;">#</span><span style="color: #008000;">判断当前登录用户是否对这篇文章做过点赞或者踩灭操作</span> obj = ArticleUpDown.objects.filter(user_id=user_id, article_id=<span style="color: #000000;">article_id).first() </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> obj: response[</span><span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span>] = False <span style="color: #008000;">#</span><span style="color: #008000;"> 更改状态</span> response[<span style="color: #800000;">"</span><span style="color: #800000;">handled</span><span style="color: #800000;">"</span>] = obj.is_up <span style="color: #008000;">#</span><span style="color: #008000;"> 获取之前的操作,返回true或者false</span> <span style="color: #0000ff;">print</span><span style="color: #000000;">(obj.is_up) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: </span><span style="color: #008000;">#</span><span style="color: #008000;">插入一条记录</span> new_obj = ArticleUpDown.objects.create(user_id=user_id, article_id=article_id, is_up=<span style="color: #000000;">is_up) ask </span><span style="color: #008000;">#</span><span style="color: #008000;"> 这一行故意出错</span> <span style="color: #0000ff;">if</span> is_up: <span style="color: #008000;">#</span><span style="color: #008000;"> 判断为推荐</span> Article.objects.filter(pk=article_id).update(up_count=F(<span style="color: #800000;">"</span><span style="color: #800000;">up_count</span><span style="color: #800000;">"</span>)+1<span style="color: #000000;">) </span><span style="color: #0000ff;">else</span>: <span style="color: #008000;">#</span><span style="color: #008000;"> 反对</span> Article.objects.filter(pk=article_id).update(down_count=F(<span style="color: #800000;">"</span><span style="color: #800000;">down_count</span><span style="color: #800000;">"</span>)+1<span style="color: #000000;">) </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> JsonResponse(response) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">"</span><span style="color: #800000;">非法请求</span><span style="color: #800000;">"</span>)</pre>
清空blog_articleupdown表,将blog_article表的up_count和down_count字段设置为0
刷新页面,重新点击,打开浏览器工具-->network
出行了500错误
查看blog_articleupdown表,多了一条记录
查看blog_article表,对应文章的up_count字段,发现还是为0
使用事务
修改digg视图函数,导入模块transaction。
使用语法很简单,将相关原子操作的代码直接tab一下,就可以了
完整代码如下:
from django.shortcuts import render,HttpResponse,redirect from django.contrib import auth from blog.models import Article,UserInfo,Blog,Category,Tag,ArticleUpDown from django.db.models import Sum,Avg,Max,Min,Count from django.db.models import F import json from django.http import JsonResponse from django.db import transaction# Create your views here.
def login(request):</span><span style="color: #0000ff;">if</span> request.method==<span style="color: #800000;">"</span><span style="color: #800000;">POST</span><span style="color: #800000;">"</span><span style="color: #000000;">: user</span>=request.POST.get(<span style="color: #800000;">"</span><span style="color: #800000;">user</span><span style="color: #800000;">"</span><span style="color: #000000;">) pwd</span>=request.POST.get(<span style="color: #800000;">"</span><span style="color: #800000;">pwd</span><span style="color: #800000;">"</span><span style="color: #000000;">) </span><span style="color: #008000;">#</span><span style="color: #008000;"> 用户验证成功,返回user对象,否则返回None</span> user=auth.authenticate(username=user,password=<span style="color: #000000;">pwd) </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> user: </span><span style="color: #008000;">#</span><span style="color: #008000;"> 登录,注册session</span> <span style="color: #008000;">#</span><span style="color: #008000;"> 全局变量 request.user=当前登陆对象(session中)</span>
auth.login(request,user)
return redirect("/index/")</span><span style="color: #0000ff;">return</span> render(request,<span style="color: #800000;">"</span><span style="color: #800000;">login.html</span><span style="color: #800000;">"</span><span style="color: #000000;">)
def index(request):
article_list=Article.objects.all()
return render(request,"index.html",{"article_list":article_list})def logout(request): # 注销
auth.logout(request)
return redirect("/index/")def query_current_site(request,username): # 查询当前站点的博客标题
# 查询当前站点的用户对象
user = UserInfo.objects.filter(username=username).first()
if not user:
return render(request, "not_found.html")
# 查询当前站点对象
blog = user.blog
return blogdef homesite(request,username,**kwargs): # 个人站点主页
print("kwargs", kwargs)blog </span>=<span style="color: #000000;"> query_current_site(request,username) </span><span style="color: #008000;">#</span><span style="color: #008000;"> 查询当前用户发布的所有文章</span> <span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> kwargs: article_list </span>= Article.objects.filter(user__username=<span style="color: #000000;">username) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: condition </span>= kwargs.get(<span style="color: #800000;">"</span><span style="color: #800000;">condition</span><span style="color: #800000;">"</span><span style="color: #000000;">) params </span>= kwargs.get(<span style="color: #800000;">"</span><span style="color: #800000;">params</span><span style="color: #800000;">"</span><span style="color: #000000;">) </span><span style="color: #008000;">#</span><span style="color: #008000;">判断分类、随笔、归档</span> <span style="color: #0000ff;">if</span> condition == <span style="color: #800000;">"</span><span style="color: #800000;">category</span><span style="color: #800000;">"</span><span style="color: #000000;">: article_list </span>= Article.objects.filter(user__username=username).filter(category__title=<span style="color: #000000;">params) </span><span style="color: #0000ff;">elif</span> condition == <span style="color: #800000;">"</span><span style="color: #800000;">tag</span><span style="color: #800000;">"</span><span style="color: #000000;">: article_list </span>= Article.objects.filter(user__username=username).filter(tags__title=<span style="color: #000000;">params) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: year, month </span>= params.split(<span style="color: #800000;">"</span><span style="color: #800000;">/</span><span style="color: #800000;">"</span><span style="color: #000000;">) article_list </span>= Article.objects.filter(user__username=username).filter(create_time__year=<span style="color: #000000;">year, create_time__month</span>=<span style="color: #000000;">month) </span><span style="color: #0000ff;">return</span> render(request,<span style="color: #800000;">"</span><span style="color: #800000;">homesite.html</span><span style="color: #800000;">"</span>,{<span style="color: #800000;">"</span><span style="color: #800000;">blog</span><span style="color: #800000;">"</span>:blog,<span style="color: #800000;">"</span><span style="color: #800000;">username</span><span style="color: #800000;">"</span>:username,<span style="color: #800000;">"</span><span style="color: #800000;">article_list</span><span style="color: #800000;">"</span><span style="color: #000000;">:article_list})
def article_detail(request,username,article_id):
blog = query_current_site(request,username)</span><span style="color: #008000;">#</span><span style="color: #008000;">查询指定id的文章</span> article_obj = Article.objects.filter(pk=<span style="color: #000000;">article_id).first() user_id </span>= UserInfo.objects.filter(username=<span style="color: #000000;">username).first().nid </span><span style="color: #0000ff;">return</span> render(request,<span style="color: #800000;">'</span><span style="color: #800000;">article_detail.html</span><span style="color: #800000;">'</span>,{<span style="color: #800000;">"</span><span style="color: #800000;">blog</span><span style="color: #800000;">"</span>:blog,<span style="color: #800000;">"</span><span style="color: #800000;">username</span><span style="color: #800000;">"</span>:username,<span style="color: #800000;">'</span><span style="color: #800000;">article_obj</span><span style="color: #800000;">'</span>:article_obj,<span style="color: #800000;">"</span><span style="color: #800000;">user_id</span><span style="color: #800000;">"</span><span style="color: #000000;">:user_id})
def digg(request):
print(request.POST)
if request.method == "POST":
#ajax发送的过来的true和false是字符串,使用json反序列化得到布尔值
is_up = json.loads(request.POST.get("is_up"))
article_id = request.POST.get("article_id")
user_id = request.user.pkresponse </span>= {<span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span>: True, <span style="color: #800000;">"</span><span style="color: #800000;">msg</span><span style="color: #800000;">"</span>: None} <span style="color: #008000;">#</span><span style="color: #008000;"> 初始状态</span> <span style="color: #008000;">#</span><span style="color: #008000;">判断当前登录用户是否对这篇文章做过点赞或者踩灭操作</span> obj = ArticleUpDown.objects.filter(user_id=user_id, article_id=<span style="color: #000000;">article_id).first() </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> obj: response[</span><span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span>] = False <span style="color: #008000;">#</span><span style="color: #008000;"> 更改状态</span> response[<span style="color: #800000;">"</span><span style="color: #800000;">handled</span><span style="color: #800000;">"</span>] = obj.is_up <span style="color: #008000;">#</span><span style="color: #008000;"> 获取之前的操作,返回true或者false</span> <span style="color: #0000ff;">print</span><span style="color: #000000;">(obj.is_up) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: with transaction.atomic(): </span><span style="color: #008000;">#</span><span style="color: #008000;">插入一条记录</span> new_obj = ArticleUpDown.objects.create(user_id=user_id, article_id=article_id, is_up=<span style="color: #000000;">is_up) ask </span><span style="color: #008000;">#</span><span style="color: #008000;"> 模拟异常</span> <span style="color: #0000ff;">if</span> is_up: <span style="color: #008000;">#</span><span style="color: #008000;"> 判断为推荐</span> Article.objects.filter(pk=article_id).update(up_count=F(<span style="color: #800000;">"</span><span style="color: #800000;">up_count</span><span style="color: #800000;">"</span>)+1<span style="color: #000000;">) </span><span style="color: #0000ff;">else</span>: <span style="color: #008000;">#</span><span style="color: #008000;"> 反对</span> Article.objects.filter(pk=article_id).update(down_count=F(<span style="color: #800000;">"</span><span style="color: #800000;">down_count</span><span style="color: #800000;">"</span>)+1<span style="color: #000000;">) </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> JsonResponse(response) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">"</span><span style="color: #800000;">非法请求</span><span style="color: #800000;">"</span>)</pre>
清空blog_articleupdown表
刷新页面,重新点击,再一次返回500错误
查看blog_articleupdown表,发现并没增加一条记录。
这样就比较合理了!删除异常代码
def digg(request): print(request.POST) if request.method == "POST": #ajax发送的过来的true和false是字符串,使用json反序列化得到布尔值 is_up = json.loads(request.POST.get("is_up")) article_id = request.POST.get("article_id") user_id = request.user.pkresponse </span>= {<span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span>: True, <span style="color: #800000;">"</span><span style="color: #800000;">msg</span><span style="color: #800000;">"</span>: None} <span style="color: #008000;">#</span><span style="color: #008000;"> 初始状态</span> <span style="color: #008000;">#</span><span style="color: #008000;">判断当前登录用户是否对这篇文章做过点赞或者踩灭操作</span> obj = ArticleUpDown.objects.filter(user_id=user_id, article_id=<span style="color: #000000;">article_id).first() </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> obj: response[</span><span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span>] = False <span style="color: #008000;">#</span><span style="color: #008000;"> 更改状态</span> response[<span style="color: #800000;">"</span><span style="color: #800000;">handled</span><span style="color: #800000;">"</span>] = obj.is_up <span style="color: #008000;">#</span><span style="color: #008000;"> 获取之前的操作,返回true或者false</span> <span style="color: #0000ff;">print</span><span style="color: #000000;">(obj.is_up) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: with transaction.atomic(): </span><span style="color: #008000;">#</span><span style="color: #008000;">插入一条记录</span> new_obj = ArticleUpDown.objects.create(user_id=user_id, article_id=article_id, is_up=<span style="color: #000000;">is_up) </span><span style="color: #0000ff;">if</span> is_up: <span style="color: #008000;">#</span><span style="color: #008000;"> 判断为推荐</span> Article.objects.filter(pk=article_id).update(up_count=F(<span style="color: #800000;">"</span><span style="color: #800000;">up_count</span><span style="color: #800000;">"</span>)+1<span style="color: #000000;">) </span><span style="color: #0000ff;">else</span>: <span style="color: #008000;">#</span><span style="color: #008000;"> 反对</span> Article.objects.filter(pk=article_id).update(down_count=F(<span style="color: #800000;">"</span><span style="color: #800000;">down_count</span><span style="color: #800000;">"</span>)+1<span style="color: #000000;">) </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> JsonResponse(response) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">"</span><span style="color: #800000;">非法请求</span><span style="color: #800000;">"</span>)</pre>
刷新页面,重新点击
查看blog_articleupdown表,发现增加了一条记录。
查看blog_article表,对应文章的up_count字段,发现为1了!
事务用起来很简单,是因为django把复杂的逻辑给封装好了!
有时间的小伙伴,还可以加一个需求,自己不能给自己点赞!
二、用户评论
评论样式
先写html的样式代码
修改article_detail.html
{% extends "base.html" %}{% block content %}
<div class="article_info">
<h4 class="text-center">{{ article_obj.title }}</h4>
<div class="content">
{{ article_obj.content|safe }}
</div>
<div id="div_digg">
<div class="diggit action">
<span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
</div>
<div class="buryit action">
<span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
</div>
</div>
<div class="clearfix"></div><div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">comment</span><span style="color: #800000;">"</span>> <p>评论列表</p> <ul <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">comment_list list-group</span><span style="color: #800000;">"</span>><span style="color: #000000;"> {</span>% <span style="color: #0000ff;">for</span> comment <span style="color: #0000ff;">in</span> comment_list %<span style="color: #000000;">} </span><li <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">list-group-item</span><span style="color: #800000;">"</span>> <div> <a href=<span style="color: #800000;">""</span>><span style="color: #008000;">#</span><span style="color: #008000;">{{ forloop.counter }}楼</a>&nbsp;&nbsp;</span> <span <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">small</span><span style="color: #800000;">"</span>>{{ comment.create_time|date:<span style="color: #800000;">"</span><span style="color: #800000;">Y-m-d H:i</span><span style="color: #800000;">"</span> }}</span>&nbsp;&<span style="color: #000000;">nbsp; </span><a href=<span style="color: #800000;">""</span>>{{ comment.user.username }}</a> <a href=<span style="color: #800000;">""</span> <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">pull-right</span><span style="color: #800000;">"</span>><span>回复</span></a> </div> <div> <p>{{ comment.content }}</p> </div> </li><span style="color: #000000;"> {</span>% endfor %<span style="color: #000000;">} </span></ul> <p>发表评论</p> <p>昵称:<input type=<span style="color: #800000;">"</span><span style="color: #800000;">text</span><span style="color: #800000;">"</span> id=<span style="color: #800000;">"</span><span style="color: #800000;">tbCommentAuthor</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">author</span><span style="color: #800000;">"</span> disabled=<span style="color: #800000;">"</span><span style="color: #800000;">disabled</span><span style="color: #800000;">"</span> size=<span style="color: #800000;">"</span><span style="color: #800000;">50</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">{{ request.user.username }}</span><span style="color: #800000;">"</span>></p> <div> <textarea name=<span style="color: #800000;">""</span> id=<span style="color: #800000;">"</span><span style="color: #800000;">comment_content</span><span style="color: #800000;">"</span> cols=<span style="color: #800000;">"</span><span style="color: #800000;">60</span><span style="color: #800000;">"</span> rows=<span style="color: #800000;">"</span><span style="color: #800000;">10</span><span style="color: #800000;">"</span>></textarea> </div> <input type=<span style="color: #800000;">"</span><span style="color: #800000;">button</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">submit</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">btn btn-default comment_btn</span><span style="color: #800000;">"</span>> </div> </div><span style="color: #000000;"> {</span>% csrf_token %<span style="color: #000000;">} </span><script><span style="color: #000000;"> $(</span><span style="color: #800000;">"</span><span style="color: #800000;">.action</span><span style="color: #800000;">"</span><span style="color: #000000;">).click(function () { {</span><span style="color: #008000;">#</span><span style="color: #008000;">hasClass() 方法检查被选元素是否包含指定的 class#}</span> var is_up = $(this).hasClass(<span style="color: #800000;">"</span><span style="color: #800000;">diggit</span><span style="color: #800000;">"</span><span style="color: #000000;">); {</span><span style="color: #008000;">#</span><span style="color: #008000;">获取提示的span标签#}</span> var _this = $(this).children(<span style="color: #800000;">"</span><span style="color: #800000;">span</span><span style="color: #800000;">"</span><span style="color: #000000;">); {</span><span style="color: #008000;">#</span><span style="color: #008000;">判断是否登录#}</span> <span style="color: #0000ff;">if</span> (<span style="color: #800000;">"</span><span style="color: #800000;">{{ request.user.username }}</span><span style="color: #800000;">"</span><span style="color: #000000;">) { $.ajax({ url: </span><span style="color: #800000;">"</span><span style="color: #800000;">/digg/</span><span style="color: #800000;">"</span><span style="color: #000000;">, type: </span><span style="color: #800000;">"</span><span style="color: #800000;">post</span><span style="color: #800000;">"</span><span style="color: #000000;">, data: { is_up: is_up, article_id: </span><span style="color: #800000;">"</span><span style="color: #800000;">{{ article_obj.pk }}</span><span style="color: #800000;">"</span><span style="color: #000000;">, csrfmiddlewaretoken: $(</span><span style="color: #800000;">"</span><span style="color: #800000;">[name='csrfmiddlewaretoken']</span><span style="color: #800000;">"</span><span style="color: #000000;">).val() }, success: function (data) { console.log(data); console.log(typeof data); </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (data.state) { </span>//<span style="color: #000000;">提交成功 var val </span>= _this.text(); //<span style="color: #000000;">获取text值 </span>//<span style="color: #000000;">在原有的基础上加1。注意:一定要进行类型转换 _this.text(parseInt(val) </span>+ 1<span style="color: #000000;">) } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { </span>//<span style="color: #000000;"> 重复提交 var val </span>= data.handled ? <span style="color: #800000;">"</span><span style="color: #800000;">您已经推荐过!</span><span style="color: #800000;">"</span> : <span style="color: #800000;">"</span><span style="color: #800000;">您已经反对过!</span><span style="color: #800000;">"</span><span style="color: #000000;">; $(</span><span style="color: #800000;">"</span><span style="color: #800000;">#digg_tips</span><span style="color: #800000;">"</span><span style="color: #000000;">).html(val); setTimeout(function () { $(</span><span style="color: #800000;">"</span><span style="color: #800000;">#digg_tips</span><span style="color: #800000;">"</span>).html(<span style="color: #800000;">""</span>) //<span style="color: #000000;">清空提示文字 }, </span>1000<span style="color: #000000;">) } } }) } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { location.href </span>= <span style="color: #800000;">"</span><span style="color: #800000;">/login/</span><span style="color: #800000;">"</span><span style="color: #000000;">; } }) </span></script><span style="color: #000000;">
{% endblock %}
修改css目录下的article_detail.css
注意放一个gif图片到img目录下
/*推荐和反对*/ #div_digg { float: right; margin-bottom: 10px; margin-right: 30px; font-size: 12px; 125px; text-align: center; margin-top: 10px; }.diggit {
float: left;
46px;
height: 52px;
background: url("/static/img/upup.gif") no-repeat;
text-align: center;
cursor: pointer;
margin-top: 2px;
padding-top: 5px;
}.buryit {
float: right;
margin-left: 20px;
46px;
height: 52px;
background: url("/static/img/downdown.gif") no-repeat;
text-align: center;
cursor: pointer;
margin-top: 2px;
padding-top: 5px;
}
.clear {
clear: both;
}#digg_tips{
color: red;
}/评论/
input.author{
background-image: url("/static/img/icon_form.gif");
background-repeat: no-repeat;
border: 1px solid #ccc;
padding: 4px 4px 4px 30px;
300px;
font-size: 13px;
}input.author {
background-position: 3px -3px;
}
刷新网页,拉到最下面,效果如下:
评论步骤
- 提交根评论请求
- 显示根评论
- render
- Ajax显示
- 提交子评论
- 显示子评论
- 评论树
发送ajax请求
查看评论表模型
class Comment(models.Model): """评论表 </span><span style="color: #800000;">"""</span><span style="color: #000000;"> nid </span>= models.AutoField(primary_key=<span style="color: #000000;">True) article </span>= models.ForeignKey(verbose_name=<span style="color: #800000;">'</span><span style="color: #800000;">评论文章</span><span style="color: #800000;">'</span>, to=<span style="color: #800000;">'</span><span style="color: #800000;">Article</span><span style="color: #800000;">'</span>, to_field=<span style="color: #800000;">'</span><span style="color: #800000;">nid</span><span style="color: #800000;">'</span>, on_delete=<span style="color: #000000;">models.CASCADE) user </span>= models.ForeignKey(verbose_name=<span style="color: #800000;">'</span><span style="color: #800000;">评论者</span><span style="color: #800000;">'</span>, to=<span style="color: #800000;">'</span><span style="color: #800000;">UserInfo</span><span style="color: #800000;">'</span>, to_field=<span style="color: #800000;">'</span><span style="color: #800000;">nid</span><span style="color: #800000;">'</span>, on_delete=<span style="color: #000000;">models.CASCADE) content </span>= models.CharField(verbose_name=<span style="color: #800000;">'</span><span style="color: #800000;">评论内容</span><span style="color: #800000;">'</span>, max_length=255<span style="color: #000000;">) create_time </span>= models.DateTimeField(verbose_name=<span style="color: #800000;">'</span><span style="color: #800000;">创建时间</span><span style="color: #800000;">'</span>, auto_now_add=<span style="color: #000000;">True) parent_comment </span>= models.ForeignKey(verbose_name=<span style="color: #800000;">"</span><span style="color: #800000;">父级评论id</span><span style="color: #800000;">"</span>, to=<span style="color: #800000;">'</span><span style="color: #800000;">Comment</span><span style="color: #800000;">'</span>,null=True, on_delete=models.CASCADE)</pre>
它有6个字段,其中nid、user、parent_comment、create_time是可选的。
user 在视图函数中,可以直接获取,不需要ajax传此参数。
parent_comment字段的值为空,表示这是一条根评论。否则为一条子评论!
那么ajax如果传一个空值,表示为根评论,否则为子评论。
create_time字段有一个属性:auto_now_add=True。
字段在实例第一次保存的时候会保存当前时间,不管你在这里是否对其赋值。但是之后的save()是可以手动赋值的。
也就是新实例化一个model,想手动存其他时间,就需要对该实例save()之后赋值然后再save()
根评论
修改article_detail.html的js代码,只需要发送3个参数即可。分别是content,atricle_id,parent_comment
{% extends "base.html" %}{% block content %}
<div class="article_info">
<h4 class="text-center">{{ article_obj.title }}</h4>
<div class="content">
{{ article_obj.content|safe }}
</div>
<div id="div_digg">
<div class="diggit action">
<span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
</div>
<div class="buryit action">
<span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
</div>
</div>
<div class="clearfix"></div><div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">comment</span><span style="color: #800000;">"</span>> <p>评论列表</p> <ul <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">comment_list list-group</span><span style="color: #800000;">"</span>><span style="color: #000000;"> {</span>% <span style="color: #0000ff;">for</span> comment <span style="color: #0000ff;">in</span> comment_list %<span style="color: #000000;">} </span><li <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">list-group-item</span><span style="color: #800000;">"</span>> <div> <a href=<span style="color: #800000;">""</span>><span style="color: #008000;">#</span><span style="color: #008000;">{{ forloop.counter }}楼</a>&nbsp;&nbsp;</span> <span <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">small</span><span style="color: #800000;">"</span>>{{ comment.create_time|date:<span style="color: #800000;">"</span><span style="color: #800000;">Y-m-d H:i</span><span style="color: #800000;">"</span> }}</span>&nbsp;&<span style="color: #000000;">nbsp; </span><a href=<span style="color: #800000;">""</span>>{{ comment.user.username }}</a> <a href=<span style="color: #800000;">""</span> <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">pull-right</span><span style="color: #800000;">"</span>><span>回复</span></a> </div> <div> <p>{{ comment.content }}</p> </div> </li><span style="color: #000000;"> {</span>% endfor %<span style="color: #000000;">} </span></ul> <p>发表评论</p> <p>昵称:<input type=<span style="color: #800000;">"</span><span style="color: #800000;">text</span><span style="color: #800000;">"</span> id=<span style="color: #800000;">"</span><span style="color: #800000;">tbCommentAuthor</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">author</span><span style="color: #800000;">"</span> disabled=<span style="color: #800000;">"</span><span style="color: #800000;">disabled</span><span style="color: #800000;">"</span> size=<span style="color: #800000;">"</span><span style="color: #800000;">50</span><span style="color: #800000;">"</span><span style="color: #000000;"> value</span>=<span style="color: #800000;">"</span><span style="color: #800000;">{{ request.user.username }}</span><span style="color: #800000;">"</span>></p> <div> <textarea name=<span style="color: #800000;">""</span> id=<span style="color: #800000;">"</span><span style="color: #800000;">comment_content</span><span style="color: #800000;">"</span> cols=<span style="color: #800000;">"</span><span style="color: #800000;">60</span><span style="color: #800000;">"</span> rows=<span style="color: #800000;">"</span><span style="color: #800000;">10</span><span style="color: #800000;">"</span>></textarea> </div> <input type=<span style="color: #800000;">"</span><span style="color: #800000;">button</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">submit</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">btn btn-default comment_btn</span><span style="color: #800000;">"</span>> </div> </div><span style="color: #000000;"> {</span>% csrf_token %<span style="color: #000000;">} </span><script> //<span style="color: #000000;"> 点赞和踩灭 $(</span><span style="color: #800000;">"</span><span style="color: #800000;">.action</span><span style="color: #800000;">"</span><span style="color: #000000;">).click(function () { {</span><span style="color: #008000;">#</span><span style="color: #008000;">hasClass() 方法检查被选元素是否包含指定的 class#}</span> var is_up = $(this).hasClass(<span style="color: #800000;">"</span><span style="color: #800000;">diggit</span><span style="color: #800000;">"</span><span style="color: #000000;">); {</span><span style="color: #008000;">#</span><span style="color: #008000;">获取提示的span标签#}</span> var _this = $(this).children(<span style="color: #800000;">"</span><span style="color: #800000;">span</span><span style="color: #800000;">"</span><span style="color: #000000;">); {</span><span style="color: #008000;">#</span><span style="color: #008000;">判断是否登录#}</span> <span style="color: #0000ff;">if</span> (<span style="color: #800000;">"</span><span style="color: #800000;">{{ request.user.username }}</span><span style="color: #800000;">"</span><span style="color: #000000;">) { $.ajax({ url: </span><span style="color: #800000;">"</span><span style="color: #800000;">/digg/</span><span style="color: #800000;">"</span><span style="color: #000000;">, type: </span><span style="color: #800000;">"</span><span style="color: #800000;">post</span><span style="color: #800000;">"</span><span style="color: #000000;">, data: { is_up: is_up, article_id: </span><span style="color: #800000;">"</span><span style="color: #800000;">{{ article_obj.pk }}</span><span style="color: #800000;">"</span><span style="color: #000000;">, csrfmiddlewaretoken: $(</span><span style="color: #800000;">"</span><span style="color: #800000;">[name='csrfmiddlewaretoken']</span><span style="color: #800000;">"</span><span style="color: #000000;">).val() }, success: function (data) { console.log(data); console.log(typeof data); </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (data.state) { </span>//<span style="color: #000000;">提交成功 var val </span>= _this.text(); //<span style="color: #000000;">获取text值 </span>//<span style="color: #000000;">在原有的基础上加1。注意:一定要进行类型转换 _this.text(parseInt(val) </span>+ 1<span style="color: #000000;">) } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { </span>//<span style="color: #000000;"> 重复提交 var val </span>= data.handled ? <span style="color: #800000;">"</span><span style="color: #800000;">您已经推荐过!</span><span style="color: #800000;">"</span> : <span style="color: #800000;">"</span><span style="color: #800000;">您已经反对过!</span><span style="color: #800000;">"</span><span style="color: #000000;">; $(</span><span style="color: #800000;">"</span><span style="color: #800000;">#digg_tips</span><span style="color: #800000;">"</span><span style="color: #000000;">).html(val); setTimeout(function () { $(</span><span style="color: #800000;">"</span><span style="color: #800000;">#digg_tips</span><span style="color: #800000;">"</span>).html(<span style="color: #800000;">""</span>) //<span style="color: #000000;">清空提示文字 }, </span>1000<span style="color: #000000;">) } } }) } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { location.href </span>= <span style="color: #800000;">"</span><span style="color: #800000;">/login/</span><span style="color: #800000;">"</span><span style="color: #000000;">; } }) </span>//<span style="color: #000000;"> 提交评论 $(</span><span style="color: #800000;">"</span><span style="color: #800000;">.comment_btn</span><span style="color: #800000;">"</span><span style="color: #000000;">).click(function () { {</span><span style="color: #008000;">#</span><span style="color: #008000;">评论内容#}</span> var content = $(<span style="color: #800000;">"</span><span style="color: #800000;">#comment_content</span><span style="color: #800000;">"</span><span style="color: #000000;">).val(); {</span><span style="color: #008000;">#</span><span style="color: #008000;">默认为空#}</span> var pid = <span style="color: #800000;">""</span><span style="color: #000000;">; $.ajax({ url: </span><span style="color: #800000;">"</span><span style="color: #800000;">/comment/</span><span style="color: #800000;">"</span><span style="color: #000000;">, type: </span><span style="color: #800000;">"</span><span style="color: #800000;">post</span><span style="color: #800000;">"</span><span style="color: #000000;">, data: { content: content, article_id: </span><span style="color: #800000;">"</span><span style="color: #800000;">{{ article_obj.pk }}</span><span style="color: #800000;">"</span><span style="color: #000000;">, pid: pid, csrfmiddlewaretoken: $(</span><span style="color: #800000;">"</span><span style="color: #800000;">[name='csrfmiddlewaretoken']</span><span style="color: #800000;">"</span><span style="color: #000000;">).val() }, success: function (data) { console.log(data); </span>//<span style="color: #000000;"> 清空输入框的内容 $(</span><span style="color: #800000;">"</span><span style="color: #800000;">#comment_content</span><span style="color: #800000;">"</span>).val(<span style="color: #800000;">""</span><span style="color: #000000;">) } }) }) </span></script><span style="color: #000000;">
{% endblock %}
修改urls.py,增加路径comment
urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), path('index/', views.index), path('logout/', views.logout), path('', views.index), #点赞或者踩灭 path('digg/', views.digg), # 评论 path('comment/', views.comment),</span><span style="color: #008000;">#</span><span style="color: #008000;">文章详情</span> re_path(<span style="color: #800000;">'</span><span style="color: #800000;">(?P<username>w+)/articles/(?P<article_id>d+)/$</span><span style="color: #800000;">'</span><span style="color: #000000;">, views.article_detail), </span><span style="color: #008000;">#</span><span style="color: #008000;"> 跳转</span> re_path(<span style="color: #800000;">'</span><span style="color: #800000;">(?P<username>w+)/(?P<condition>category|tag|achrive)/(?P<params>.*)/$</span><span style="color: #800000;">'</span><span style="color: #000000;">, views.homesite), </span><span style="color: #008000;">#</span><span style="color: #008000;"> 个人站点</span> re_path(<span style="color: #800000;">'</span><span style="color: #800000;">(?P<username>w+)/$</span><span style="color: #800000;">'</span><span style="color: #000000;">, views.homesite),
]
修改views.py,增加视图函数comment,完整代码如下:
from django.shortcuts import render,HttpResponse,redirect from django.contrib import auth from blog.models import Article,UserInfo,Blog,Category,Tag,ArticleUpDown,Comment from django.db.models import Sum,Avg,Max,Min,Count from django.db.models import F import json from django.http import JsonResponse from django.db import transaction# Create your views here.
def login(request):</span><span style="color: #0000ff;">if</span> request.method==<span style="color: #800000;">"</span><span style="color: #800000;">POST</span><span style="color: #800000;">"</span><span style="color: #000000;">: user</span>=request.POST.get(<span style="color: #800000;">"</span><span style="color: #800000;">user</span><span style="color: #800000;">"</span><span style="color: #000000;">) pwd</span>=request.POST.get(<span style="color: #800000;">"</span><span style="color: #800000;">pwd</span><span style="color: #800000;">"</span><span style="color: #000000;">) </span><span style="color: #008000;">#</span><span style="color: #008000;"> 用户验证成功,返回user对象,否则返回None</span> user=auth.authenticate(username=user,password=<span style="color: #000000;">pwd) </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> user: </span><span style="color: #008000;">#</span><span style="color: #008000;"> 登录,注册session</span> <span style="color: #008000;">#</span><span style="color: #008000;"> 全局变量 request.user=当前登陆对象(session中)</span>
auth.login(request,user)
return redirect("/index/")</span><span style="color: #0000ff;">return</span> render(request,<span style="color: #800000;">"</span><span style="color: #800000;">login.html</span><span style="color: #800000;">"</span><span style="color: #000000;">)
def index(request):
article_list=Article.objects.all()
return render(request,"index.html",{"article_list":article_list})def logout(request): # 注销
auth.logout(request)
return redirect("/index/")def query_current_site(request,username): # 查询当前站点的博客标题
# 查询当前站点的用户对象
user = UserInfo.objects.filter(username=username).first()
if not user:
return render(request, "not_found.html")
# 查询当前站点对象
blog = user.blog
return blogdef homesite(request,username,**kwargs): # 个人站点主页
print("kwargs", kwargs)blog </span>=<span style="color: #000000;"> query_current_site(request,username) </span><span style="color: #008000;">#</span><span style="color: #008000;"> 查询当前用户发布的所有文章</span> <span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> kwargs: article_list </span>= Article.objects.filter(user__username=<span style="color: #000000;">username) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: condition </span>= kwargs.get(<span style="color: #800000;">"</span><span style="color: #800000;">condition</span><span style="color: #800000;">"</span><span style="color: #000000;">) params </span>= kwargs.get(<span style="color: #800000;">"</span><span style="color: #800000;">params</span><span style="color: #800000;">"</span><span style="color: #000000;">) </span><span style="color: #008000;">#</span><span style="color: #008000;">判断分类、随笔、归档</span> <span style="color: #0000ff;">if</span> condition == <span style="color: #800000;">"</span><span style="color: #800000;">category</span><span style="color: #800000;">"</span><span style="color: #000000;">: article_list </span>= Article.objects.filter(user__username=username).filter(category__title=<span style="color: #000000;">params) </span><span style="color: #0000ff;">elif</span> condition == <span style="color: #800000;">"</span><span style="color: #800000;">tag</span><span style="color: #800000;">"</span><span style="color: #000000;">: article_list </span>= Article.objects.filter(user__username=username).filter(tags__title=<span style="color: #000000;">params) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: year, month </span>= params.split(<span style="color: #800000;">"</span><span style="color: #800000;">/</span><span style="color: #800000;">"</span><span style="color: #000000;">) article_list </span>= Article.objects.filter(user__username=username).filter(create_time__year=<span style="color: #000000;">year, create_time__month</span>=<span style="color: #000000;">month) </span><span style="color: #0000ff;">return</span> render(request,<span style="color: #800000;">"</span><span style="color: #800000;">homesite.html</span><span style="color: #800000;">"</span>,{<span style="color: #800000;">"</span><span style="color: #800000;">blog</span><span style="color: #800000;">"</span>:blog,<span style="color: #800000;">"</span><span style="color: #800000;">username</span><span style="color: #800000;">"</span>:username,<span style="color: #800000;">"</span><span style="color: #800000;">article_list</span><span style="color: #800000;">"</span><span style="color: #000000;">:article_list})
def article_detail(request,username,article_id):
blog = query_current_site(request,username)</span><span style="color: #008000;">#</span><span style="color: #008000;">查询指定id的文章</span> article_obj = Article.objects.filter(pk=<span style="color: #000000;">article_id).first() user_id </span>= UserInfo.objects.filter(username=<span style="color: #000000;">username).first().nid </span><span style="color: #0000ff;">return</span> render(request,<span style="color: #800000;">'</span><span style="color: #800000;">article_detail.html</span><span style="color: #800000;">'</span>,{<span style="color: #800000;">"</span><span style="color: #800000;">blog</span><span style="color: #800000;">"</span>:blog,<span style="color: #800000;">"</span><span style="color: #800000;">username</span><span style="color: #800000;">"</span>:username,<span style="color: #800000;">'</span><span style="color: #800000;">article_obj</span><span style="color: #800000;">'</span>:article_obj,<span style="color: #800000;">"</span><span style="color: #800000;">user_id</span><span style="color: #800000;">"</span><span style="color: #000000;">:user_id})
def digg(request):
print(request.POST)
if request.method == "POST":
#ajax发送的过来的true和false是字符串,使用json反序列化得到布尔值
is_up = json.loads(request.POST.get("is_up"))
article_id = request.POST.get("article_id")
user_id = request.user.pkresponse </span>= {<span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span>: True, <span style="color: #800000;">"</span><span style="color: #800000;">msg</span><span style="color: #800000;">"</span>: None} <span style="color: #008000;">#</span><span style="color: #008000;"> 初始状态</span> <span style="color: #008000;">#</span><span style="color: #008000;">判断当前登录用户是否对这篇文章做过点赞或者踩灭操作</span> obj = ArticleUpDown.objects.filter(user_id=user_id, article_id=<span style="color: #000000;">article_id).first() </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> obj: response[</span><span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span>] = False <span style="color: #008000;">#</span><span style="color: #008000;"> 更改状态</span> response[<span style="color: #800000;">"</span><span style="color: #800000;">handled</span><span style="color: #800000;">"</span>] = obj.is_up <span style="color: #008000;">#</span><span style="color: #008000;"> 获取之前的操作,返回true或者false</span> <span style="color: #0000ff;">print</span><span style="color: #000000;">(obj.is_up) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: with transaction.atomic(): </span><span style="color: #008000;">#</span><span style="color: #008000;">插入一条记录</span> new_obj = ArticleUpDown.objects.create(user_id=user_id, article_id=article_id, is_up=<span style="color: #000000;">is_up) </span><span style="color: #0000ff;">if</span> is_up: <span style="color: #008000;">#</span><span style="color: #008000;"> 判断为推荐</span> Article.objects.filter(pk=article_id).update(up_count=F(<span style="color: #800000;">"</span><span style="color: #800000;">up_count</span><span style="color: #800000;">"</span>)+1<span style="color: #000000;">) </span><span style="color: #0000ff;">else</span>: <span style="color: #008000;">#</span><span style="color: #008000;"> 反对</span> Article.objects.filter(pk=article_id).update(down_count=F(<span style="color: #800000;">"</span><span style="color: #800000;">down_count</span><span style="color: #800000;">"</span>)+1<span style="color: #000000;">) </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> JsonResponse(response) </span><span style="color: #0000ff;">else</span><span style="color: #000000;">: </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">"</span><span style="color: #800000;">非法请求</span><span style="color: #800000;">"</span><span style="color: #000000;">)
def comment(request):
print(request.POST)
if request.method == "POST":
# 获取数据
user_id = request.user.pk
article_id = request.POST.get("article_id")
content = request.POST.get("content")
pid = request.POST.get("pid")
# 生成评论对象
with transaction.atomic(): # 增加事务
# 评论表增加一条记录
comment = Comment.objects.create(user_id=user_id, article_id=article_id, content=content, parent_comment_id=pid)
# 当前文章的评论数加1
Article.objects.filter(pk=article_id).update(comment_count=F("comment_count") + 1)response </span>= {<span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span>: False} <span style="color: #008000;">#</span><span style="color: #008000;"> 初始状态</span> <span style="color: #0000ff;">if</span> comment.user_id: <span style="color: #008000;">#</span><span style="color: #008000;"> 判断返回值</span> response = {<span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span><span style="color: #000000;">: True} </span><span style="color: #0000ff;">return</span> JsonResponse(response) <span style="color: #008000;">#</span><span style="color: #008000;"> 返回json对象</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">: </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">"</span><span style="color: #800000;">非法请求</span><span style="color: #800000;">"</span>)</pre>
刷新网页,发表一条评论
查看表blog_comment,多了一条记录
查看blog_article表,对应的comment_count值,数值加1了。
渲染评论
修改article_detail视图函数,将评论列表传给模板
def article_detail(request,username,article_id): blog = query_current_site(request,username)</span><span style="color: #008000;">#</span><span style="color: #008000;">查询指定id的文章</span> article_obj = Article.objects.filter(pk=<span style="color: #000000;">article_id).first() user_id </span>= UserInfo.objects.filter(username=<span style="color: #000000;">username).first().nid comment_list </span>= Comment.objects.filter(article_id=<span style="color: #000000;">article_id) dict </span>= {<span style="color: #800000;">"</span><span style="color: #800000;">blog</span><span style="color: #800000;">"</span><span style="color: #000000;">:blog, </span><span style="color: #800000;">"</span><span style="color: #800000;">username</span><span style="color: #800000;">"</span><span style="color: #000000;">:username, </span><span style="color: #800000;">'</span><span style="color: #800000;">article_obj</span><span style="color: #800000;">'</span><span style="color: #000000;">:article_obj, </span><span style="color: #800000;">"</span><span style="color: #800000;">user_id</span><span style="color: #800000;">"</span><span style="color: #000000;">:user_id, </span><span style="color: #800000;">"</span><span style="color: #800000;">comment_list</span><span style="color: #800000;">"</span><span style="color: #000000;">:comment_list, } </span><span style="color: #0000ff;">return</span> render(request,<span style="color: #800000;">'</span><span style="color: #800000;">article_detail.html</span><span style="color: #800000;">'</span>,dict)</pre>
修改article_detail.html,使用for循环,遍历列表
{% extends "base.html" %}{% block content %}
<div class="article_info">
<h4 class="text-center">{{ article_obj.title }}</h4>
<div class="content">
{{ article_obj.content|safe }}
</div>
<div id="div_digg">
<div class="diggit action">
<span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
</div>
<div class="buryit action">
<span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
</div>
</div>
<div class="clearfix"></div><div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">comment</span><span style="color: #800000;">"</span>> <p>评论列表</p> <ul <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">comment_list list-group</span><span style="color: #800000;">"</span>><span style="color: #000000;"> {</span>% <span style="color: #0000ff;">for</span> comment <span style="color: #0000ff;">in</span> comment_list %<span style="color: #000000;">} </span><li <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">list-group-item</span><span style="color: #800000;">"</span>> <div> <a href=<span style="color: #800000;">""</span>><span style="color: #008000;">#</span><span style="color: #008000;">{{ forloop.counter }}楼</a>&nbsp;&nbsp;</span> <span <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">small</span><span style="color: #800000;">"</span>>{{ comment.create_time|date:<span style="color: #800000;">"</span><span style="color: #800000;">Y-m-d H:i</span><span style="color: #800000;">"</span> }}</span>&nbsp;&<span style="color: #000000;">nbsp; </span><a href=<span style="color: #800000;">""</span>>{{ comment.user.username }}</a> <a href=<span style="color: #800000;">""</span> <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">pull-right</span><span style="color: #800000;">"</span>><span>回复</span></a> </div> <div> <p>{{ comment.content }}</p> </div> </li><span style="color: #000000;"> {</span>% endfor %<span style="color: #000000;">} </span></ul> <p>发表评论</p> <p>昵称:<input type=<span style="color: #800000;">"</span><span style="color: #800000;">text</span><span style="color: #800000;">"</span> id=<span style="color: #800000;">"</span><span style="color: #800000;">tbCommentAuthor</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">author</span><span style="color: #800000;">"</span> disabled=<span style="color: #800000;">"</span><span style="color: #800000;">disabled</span><span style="color: #800000;">"</span> size=<span style="color: #800000;">"</span><span style="color: #800000;">50</span><span style="color: #800000;">"</span><span style="color: #000000;"> value</span>=<span style="color: #800000;">"</span><span style="color: #800000;">{{ request.user.username }}</span><span style="color: #800000;">"</span>></p> <div> <textarea name=<span style="color: #800000;">""</span> id=<span style="color: #800000;">"</span><span style="color: #800000;">comment_content</span><span style="color: #800000;">"</span> cols=<span style="color: #800000;">"</span><span style="color: #800000;">60</span><span style="color: #800000;">"</span> rows=<span style="color: #800000;">"</span><span style="color: #800000;">10</span><span style="color: #800000;">"</span>></textarea> </div> <input type=<span style="color: #800000;">"</span><span style="color: #800000;">button</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">submit</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">btn btn-default comment_btn</span><span style="color: #800000;">"</span>> </div> </div><span style="color: #000000;"> {</span>% csrf_token %<span style="color: #000000;">} </span><script> //<span style="color: #000000;"> 点赞和踩灭 $(</span><span style="color: #800000;">"</span><span style="color: #800000;">.action</span><span style="color: #800000;">"</span><span style="color: #000000;">).click(function () { {</span><span style="color: #008000;">#</span><span style="color: #008000;">hasClass() 方法检查被选元素是否包含指定的 class#}</span> var is_up = $(this).hasClass(<span style="color: #800000;">"</span><span style="color: #800000;">diggit</span><span style="color: #800000;">"</span><span style="color: #000000;">); {</span><span style="color: #008000;">#</span><span style="color: #008000;">获取提示的span标签#}</span> var _this = $(this).children(<span style="color: #800000;">"</span><span style="color: #800000;">span</span><span style="color: #800000;">"</span><span style="color: #000000;">); {</span><span style="color: #008000;">#</span><span style="color: #008000;">判断是否登录#}</span> <span style="color: #0000ff;">if</span> (<span style="color: #800000;">"</span><span style="color: #800000;">{{ request.user.username }}</span><span style="color: #800000;">"</span><span style="color: #000000;">) { $.ajax({ url: </span><span style="color: #800000;">"</span><span style="color: #800000;">/digg/</span><span style="color: #800000;">"</span><span style="color: #000000;">, type: </span><span style="color: #800000;">"</span><span style="color: #800000;">post</span><span style="color: #800000;">"</span><span style="color: #000000;">, data: { is_up: is_up, article_id: </span><span style="color: #800000;">"</span><span style="color: #800000;">{{ article_obj.pk }}</span><span style="color: #800000;">"</span><span style="color: #000000;">, csrfmiddlewaretoken: $(</span><span style="color: #800000;">"</span><span style="color: #800000;">[name='csrfmiddlewaretoken']</span><span style="color: #800000;">"</span><span style="color: #000000;">).val() }, success: function (data) { console.log(data); console.log(typeof data); </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (data.state) { </span>//<span style="color: #000000;">提交成功 var val </span>= _this.text(); //<span style="color: #000000;">获取text值 </span>//<span style="color: #000000;">在原有的基础上加1。注意:一定要进行类型转换 _this.text(parseInt(val) </span>+ 1<span style="color: #000000;">) } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { </span>//<span style="color: #000000;"> 重复提交 var val </span>= data.handled ? <span style="color: #800000;">"</span><span style="color: #800000;">您已经推荐过!</span><span style="color: #800000;">"</span> : <span style="color: #800000;">"</span><span style="color: #800000;">您已经反对过!</span><span style="color: #800000;">"</span><span style="color: #000000;">; $(</span><span style="color: #800000;">"</span><span style="color: #800000;">#digg_tips</span><span style="color: #800000;">"</span><span style="color: #000000;">).html(val); setTimeout(function () { $(</span><span style="color: #800000;">"</span><span style="color: #800000;">#digg_tips</span><span style="color: #800000;">"</span>).html(<span style="color: #800000;">""</span>) //<span style="color: #000000;">清空提示文字 }, </span>1000<span style="color: #000000;">) } } }) } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { location.href </span>= <span style="color: #800000;">"</span><span style="color: #800000;">/login/</span><span style="color: #800000;">"</span><span style="color: #000000;">; } }) </span>//<span style="color: #000000;"> 提交评论 $(</span><span style="color: #800000;">"</span><span style="color: #800000;">.comment_btn</span><span style="color: #800000;">"</span><span style="color: #000000;">).click(function () { {</span><span style="color: #008000;">#</span><span style="color: #008000;">评论内容#}</span> var content = $(<span style="color: #800000;">"</span><span style="color: #800000;">#comment_content</span><span style="color: #800000;">"</span><span style="color: #000000;">).val(); {</span><span style="color: #008000;">#</span><span style="color: #008000;">默认为空#}</span> var pid = <span style="color: #800000;">""</span><span style="color: #000000;">; $.ajax({ url: </span><span style="color: #800000;">"</span><span style="color: #800000;">/comment/</span><span style="color: #800000;">"</span><span style="color: #000000;">, type: </span><span style="color: #800000;">"</span><span style="color: #800000;">post</span><span style="color: #800000;">"</span><span style="color: #000000;">, data: { content: content, article_id: </span><span style="color: #800000;">"</span><span style="color: #800000;">{{ article_obj.pk }}</span><span style="color: #800000;">"</span><span style="color: #000000;">, pid: pid, csrfmiddlewaretoken: $(</span><span style="color: #800000;">"</span><span style="color: #800000;">[name='csrfmiddlewaretoken']</span><span style="color: #800000;">"</span><span style="color: #000000;">).val() }, success: function (data) { console.log(data); </span>//<span style="color: #000000;"> 清空输入框的内容 $(</span><span style="color: #800000;">"</span><span style="color: #800000;">#comment_content</span><span style="color: #800000;">"</span>).val(<span style="color: #800000;">""</span><span style="color: #000000;">) } }) }) </span></script><span style="color: #000000;">
{% endblock %}
刷新网页,效果如下:
评论实时展示
上面提交评论后,网页不能立即看到,需要刷新之后,才能看到。这样体验不好!
查看博客园的评论,提交之后,会立即看到评论。此时不会显示楼层,只会显示评论内容!
那么只需要提交成功之后,操作DOM,在评论列表中,追加一段li标签,展示一下,就可以了!
数据获取问题
那么内容从何而来呢?
1.直接从html中获取相关数据
2.让服务器返回相关数据,从响应体中取数据。
针对这2种方式,我们选择第2种!
为什么不选择第一种呢?因为第一种是原始输入框中的值,那么存储到数据后之后。就不一定还是输入框的值!
服务器存储到数据库之前,会将提交的数据,做一次处理!
我们想要的效果,就是不论是DOM操作,追加一段html代码。还是刷新网页,加载评论。这2种方式,评论内容是一摸一样的!
所以,我们必须选择第二种方案,让服务器返回存储的值给ajax,ajax操作DOM,最加一段html代码,给用户展示!
数据展示
修改comment视图函数,返回3个变量给ajax
def comment(request): print(request.POST) if request.method == "POST": # 获取数据 user_id = request.user.pk article_id = request.POST.get("article_id") content = request.POST.get("content") pid = request.POST.get("pid") # 生成评论对象 with transaction.atomic(): # 增加事务 # 评论表增加一条记录 comment = Comment.objects.create(user_id=user_id, article_id=article_id, content=content, parent_comment_id=pid) # 当前文章的评论数加1 Article.objects.filter(pk=article_id).update(comment_count=F("comment_count") + 1)response </span>= {<span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span>: False} <span style="color: #008000;">#</span><span style="color: #008000;"> 初始状态</span> <span style="color: #0000ff;">if</span> comment.user_id: <span style="color: #008000;">#</span><span style="color: #008000;"> 判断返回值</span> response = {<span style="color: #800000;">"</span><span style="color: #800000;">state</span><span style="color: #800000;">"</span><span style="color: #000000;">: True} </span><span style="color: #008000;">#</span><span style="color: #008000;">响应体增加3个变量</span> response[<span style="color: #800000;">"</span><span style="color: #800000;">timer</span><span style="color: #800000;">"</span>] = comment.create_time.strftime(<span style="color: #800000;">"</span><span style="color: #800000;">%Y-%m-%d %X</span><span style="color: #800000;">"</span><span style="color: #000000;">) response[</span><span style="color: #800000;">"</span><span style="color: #800000;">content</span><span style="color: #800000;">"</span>] =<span style="color: #000000;"> comment.content response[</span><span style="color: #800000;">"</span><span style="color: #800000;">user</span><span style="color: #800000;">"</span>] =<span style="color: #000000;"> request.user.username </span><span style="color: #0000ff;">return</span> JsonResponse(response) <span style="color: #008000;">#</span><span style="color: #008000;"> 返回json对象</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">: </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">"</span><span style="color: #800000;">非法请求</span><span style="color: #800000;">"</span>)</pre>
修改article_detail.html中的js代码,使用append最加一段li标签
{% extends "base.html" %}{% block content %}
<div class="article_info">
<h4 class="text-center">{{ article_obj.title }}</h4>
<div class="content">
{{ article_obj.content|safe }}
</div>
<div id="div_digg">
<div class="diggit action">
<span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
</div>
<div class="buryit action">
<span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
</div>
</div>
<div class="clearfix"></div><div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">comment</span><span style="color: #800000;">"</span>> <p>评论列表</p> <ul <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">comment_list list-group</span><span style="color: #800000;">"</span>><span style="color: #000000;"> {</span>% <span style="color: #0000ff;">for</span> comment <span style="color: #0000ff;">in</span> comment_list %<span style="color: #000000;">} </span><li <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">list-group-item</span><span style="color: #800000;">"</span>> <div> <a href=<span style="color: #800000;">""</span>><span style="color: #008000;">#</span><span style="color: #008000;">{{ forloop.counter }}楼</a>&nbsp;&nbsp;</span> <span <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">small</span><span style="color: #800000;">"</span>>{{ comment.create_time|date:<span style="color: #800000;">"</span><span style="color: #800000;">Y-m-d H:i</span><span style="color: #800000;">"</span> }}</span>&nbsp;&<span style="color: #000000;">nbsp; </span><a href=<span style="color: #800000;">""</span>>{{ comment.user.username }}</a> <a href=<span style="color: #800000;">""</span> <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">pull-right</span><span style="color: #800000;">"</span>><span>回复</span></a> </div> <div> <p>{{ comment.content }}</p> </div> </li><span style="color: #000000;"> {</span>% endfor %<span style="color: #000000;">} </span></ul> <p>发表评论</p> <p>昵称:<input type=<span style="color: #800000;">"</span><span style="color: #800000;">text</span><span style="color: #800000;">"</span> id=<span style="color: #800000;">"</span><span style="color: #800000;">tbCommentAuthor</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">author</span><span style="color: #800000;">"</span> disabled=<span style="color: #800000;">"</span><span style="color: #800000;">disabled</span><span style="color: #800000;">"</span> size=<span style="color: #800000;">"</span><span style="color: #800000;">50</span><span style="color: #800000;">"</span><span style="color: #000000;"> value</span>=<span style="color: #800000;">"</span><span style="color: #800000;">{{ request.user.username }}</span><span style="color: #800000;">"</span>></p> <div> <textarea name=<span style="color: #800000;">""</span> id=<span style="color: #800000;">"</span><span style="color: #800000;">comment_content</span><span style="color: #800000;">"</span> cols=<span style="color: #800000;">"</span><span style="color: #800000;">60</span><span style="color: #800000;">"</span> rows=<span style="color: #800000;">"</span><span style="color: #800000;">10</span><span style="color: #800000;">"</span>></textarea> </div> <input type=<span style="color: #800000;">"</span><span style="color: #800000;">button</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">submit</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">btn btn-default comment_btn</span><span style="color: #800000;">"</span>> </div> </div><span style="color: #000000;"> {</span>% csrf_token %<span style="color: #000000;">} </span><script> //<span style="color: #000000;"> 点赞和踩灭 $(</span><span style="color: #800000;">"</span><span style="color: #800000;">.action</span><span style="color: #800000;">"</span><span style="color: #000000;">).click(function () { {</span><span style="color: #008000;">#</span><span style="color: #008000;">hasClass() 方法检查被选元素是否包含指定的 class#}</span> var is_up = $(this).hasClass(<span style="color: #800000;">"</span><span style="color: #800000;">diggit</span><span style="color: #800000;">"</span><span style="color: #000000;">); {</span><span style="color: #008000;">#</span><span style="color: #008000;">获取提示的span标签#}</span> var _this = $(this).children(<span style="color: #800000;">"</span><span style="color: #800000;">span</span><span style="color: #800000;">"</span><span style="color: #000000;">); {</span><span style="color: #008000;">#</span><span style="color: #008000;">判断是否登录#}</span> <span style="color: #0000ff;">if</span> (<span style="color: #800000;">"</span><span style="color: #800000;">{{ request.user.username }}</span><span style="color: #800000;">"</span><span style="color: #000000;">) { $.ajax({ url: </span><span style="color: #800000;">"</span><span style="color: #800000;">/digg/</span><span style="color: #800000;">"</span><span style="color: #000000;">, type: </span><span style="color: #800000;">"</span><span style="color: #800000;">post</span><span style="color: #800000;">"</span><span style="color: #000000;">, data: { is_up: is_up, article_id: </span><span style="color: #800000;">"</span><span style="color: #800000;">{{ article_obj.pk }}</span><span style="color: #800000;">"</span><span style="color: #000000;">, csrfmiddlewaretoken: $(</span><span style="color: #800000;">"</span><span style="color: #800000;">[name='csrfmiddlewaretoken']</span><span style="color: #800000;">"</span><span style="color: #000000;">).val() }, success: function (data) { console.log(data); console.log(typeof data); </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (data.state) { </span>//<span style="color: #000000;">提交成功 var val </span>= _this.text(); //<span style="color: #000000;">获取text值 </span>//<span style="color: #000000;">在原有的基础上加1。注意:一定要进行类型转换 _this.text(parseInt(val) </span>+ 1<span style="color: #000000;">) } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { </span>//<span style="color: #000000;"> 重复提交 var val </span>= data.handled ? <span style="color: #800000;">"</span><span style="color: #800000;">您已经推荐过!</span><span style="color: #800000;">"</span> : <span style="color: #800000;">"</span><span style="color: #800000;">您已经反对过!</span><span style="color: #800000;">"</span><span style="color: #000000;">; $(</span><span style="color: #800000;">"</span><span style="color: #800000;">#digg_tips</span><span style="color: #800000;">"</span><span style="color: #000000;">).html(val); setTimeout(function () { $(</span><span style="color: #800000;">"</span><span style="color: #800000;">#digg_tips</span><span style="color: #800000;">"</span>).html(<span style="color: #800000;">""</span>) //<span style="color: #000000;">清空提示文字 }, </span>1000<span style="color: #000000;">) } } }) } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { location.href </span>= <span style="color: #800000;">"</span><span style="color: #800000;">/login/</span><span style="color: #800000;">"</span><span style="color: #000000;">; } }) </span>//<span style="color: #000000;"> 提交评论 $(</span><span style="color: #800000;">"</span><span style="color: #800000;">.comment_btn</span><span style="color: #800000;">"</span><span style="color: #000000;">).click(function () { {</span><span style="color: #008000;">#</span><span style="color: #008000;">评论内容#}</span> var content = $(<span style="color: #800000;">"</span><span style="color: #800000;">#comment_content</span><span style="color: #800000;">"</span><span style="color: #000000;">).val(); {</span><span style="color: #008000;">#</span><span style="color: #008000;">默认为空#}</span> var pid = <span style="color: #800000;">""</span><span style="color: #000000;">; $.ajax({ url: </span><span style="color: #800000;">"</span><span style="color: #800000;">/comment/</span><span style="color: #800000;">"</span><span style="color: #000000;">, type: </span><span style="color: #800000;">"</span><span style="color: #800000;">post</span><span style="color: #800000;">"</span><span style="color: #000000;">, data: { content: content, article_id: </span><span style="color: #800000;">"</span><span style="color: #800000;">{{ article_obj.pk }}</span><span style="color: #800000;">"</span><span style="color: #000000;">, pid: pid, csrfmiddlewaretoken: $(</span><span style="color: #800000;">"</span><span style="color: #800000;">[name='csrfmiddlewaretoken']</span><span style="color: #800000;">"</span><span style="color: #000000;">).val() }, success: function (data) { console.log(data); {</span><span style="color: #008000;">#</span><span style="color: #008000;">获取3个值#}</span> var comment_time =<span style="color: #000000;"> data.timer; var comment_content </span>=<span style="color: #000000;"> data.content; var comment_user </span>=<span style="color: #000000;"> data.user; {</span><span style="color: #008000;">#</span><span style="color: #008000;">组织li标签#}</span> var $li = ` <li <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">list-group-item</span><span style="color: #800000;">"</span>> <div> <span <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">small</span><span style="color: #800000;">"</span>>${comment_time}</span>&nbsp;&<span style="color: #000000;">nbsp; </span><a href=<span style="color: #800000;">""</span>>${comment_user}</a> </div> <div> <p>${comment_content}</p> </div> </li><span style="color: #000000;">`; {</span><span style="color: #008000;">#</span><span style="color: #008000;">追加到评论列表中#}</span> $(<span style="color: #800000;">"</span><span style="color: #800000;">.comment_list</span><span style="color: #800000;">"</span><span style="color: #000000;">).append($li); </span>//<span style="color: #000000;"> 清空输入框的内容 $(</span><span style="color: #800000;">"</span><span style="color: #800000;">#comment_content</span><span style="color: #800000;">"</span>).val(<span style="color: #800000;">""</span><span style="color: #000000;">) } }) }) </span></script><span style="color: #000000;">
{% endblock %}
刷新网页,重新评论,效果如下:
评论可以实时展示了
刷新网页,效果如下:
显示出楼层
参考资料:
转载声明:
作者:肖祥
出处: https://www.cnblogs.com/xiao987334176/