blog开发之文章详情页
文章详情页
文章详情页主要内容:
1.文章内容展示
2.评论和点赞
页面效果:
视图代码:
def article_detail(request, username, article_id): user_obj = models.UserInfo.objects.filter(username=username).first() if not user_obj: return render(request, 'blog/not_found.html') blog = user_obj.blog article_obj = models.Article.objects.filter(nid=article_id).first() comment_list = models.Comment.objects.filter(user=user_obj).all() return render(request, 'blog/article_detail.html', {'article_obj': article_obj, 'username': username, 'blog': blog, 'comment_list': comment_list}) def digg(request): if request.method == 'POST': res = BaseResponse() user = request.user if not user: res.code = 2002 res.error = '请先登录' return JsonResponse(res.dict) is_up = json.loads(request.POST.get('is_up')) article_id = request.POST.get('article_id') article_obj = models.Article.objects.filter(pk=article_id) if not article_obj.first(): res.code = 2004 res.error = '文章不存在!' return JsonResponse(res.dict) up_down_obj = models.ArticleUpDown.objects.filter(user=user, article_id=article_id).first() if up_down_obj: res.code = 2003 res.error = '你已经推荐过了' if up_down_obj.is_up else '你已经反对过了' return JsonResponse(res.dict) models.ArticleUpDown.objects.create(user=user, article_id=article_id, is_up=is_up) if is_up: article_obj.update(up_count=F('up_count') + 1) else: article_obj.update(down_count=F('down_count') + 1) return JsonResponse(res.dict) def comment(request): res = BaseResponse() article_id = request.POST.get('article_id') content = request.POST.get('content') pid = request.POST.get('pid') if not request.user.is_authenticated: res.code = 3000 res.error = '请先登录' return JsonResponse(res.dict) user_id = request.user.pk with transaction.atomic(): models.Comment.objects.create(user_id=user_id, article_id=article_id, content=content, parent_comment_id=pid) models.Article.objects.filter(pk=article_id).update(comment_count=F('comment_count') + 1) return JsonResponse(res.dict)
注意:
1.评论完成后,需要对评论表增加一条数据,还需要对文章表的评论数做加1操作。用到Django提供的事务,来保证数据完整性。
article_detail页面
{% extends 'blog/base.html' %} {% block content %} {% csrf_token %} <div class="article_info"> <h3 class="text-center">{{ article_obj.title }}</h3> <div class="content">{{ article_obj.content|safe }}</div> </div> <div class="clearfix"> <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 style="clear: both"></div> <div class="diggword" id="digg_tips" style="color: red;"></div> </div> </div> <div class="comments"> <p>评论列表</p> <ul class="list-group comment_list"> {% for comment in comment_list %} <li class="list-group-item"> <div> <a href=""># {{ forloop.counter }}楼</a> <a href=""><span>{{ comment.user.username }}</span></a> <span>{{ comment.create_time|date:'Y-m-d' }}</span> <a class="btn btn-info pull-right reply_btn" username="{{ comment.user.username }}" comment_pk="{{ comment.pk }}" id="reply_btn">回复</a> </div> {% if comment.parent_comment_id %} <div class="pid_info well"> <p>回复于{{ comment.parent_comment.user.username }}:</p> </div> {% endif %} <div class="comment_con"> <p>{{ comment.content }}</p> </div> </li> {% endfor %} </ul> <p>发表评论</p> <p>昵称:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50" value="{{ request.user.username }}"> </p> <p>评论内容:</p> <textarea name="" id="comment_content" cols="60" rows="10"></textarea> <p> <button class="btn btn-default comment_btn">提交评论</button> <span id="comment_tips"></span> </p> </div> {% endblock %} {% block js %} <script> // 点赞 $('#div_digg .action').click(function () { var is_up = $(this).hasClass('diggit'); var $obj = $(this).children('span'); $.ajax({ url: '/blog/digg/', type: 'post', data: { csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val(), is_up: is_up, article_id: "{{ article_obj.pk }}" }, success: function (data) { console.log(data); if (data.code === 1000) { var val = parseInt($obj.text()); $obj.text(val + 1); } else { $('#digg_tips').text(data.error); setTimeout(function () { $('#digg_tips').text(''); }, 1500) } } }) }); // 提交评论 var pid = ''; $('.comment_btn').click(function () { var content = $('#comment_content').val(); $.ajax({ url: '/blog/comment/', type: 'post', data:{ csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val(), article_id: "{{ article_obj.pk }}", content: content, pid: pid }, success: function (data) { console.log(data); if(data.code===1000){ $('#comment_tips').text('评论成功!请刷新查看。').css({"color":"green","margin":"10px"}); setTimeout(function () { $('#comment_tips').text(''); },1500); }else{ // 失败 $('#comment_tips').text(data.error).css({"color":"red","margin":"10px"}); setTimeout(function () { $('#comment_tips').text(''); },1500) } } }) }); // 回复按钮 $(".reply_btn").click(function () { $('#comment_content').focus(); var val = '@' + $(this).attr('username')+'\n'; $('#comment_content').val(val); pid = $(this).attr('comment_pk'); }) </script> {% endblock %}
注意:
1.点完赞后,需要对页面的点赞数+1,通过parseInt先转换整形再操作。
var val = parseInt($obj.text());
$obj.text(val + 1);