博客评论相关

博客文章详情页搭建

{% extends 'base.html' %}
{% block css %}
<style>
#div_digg {
float: right;
margin-bottom: 10px;
margin-right: 30px;
font-size: 12px;
width: 125px;
text-align: center;
margin-top: 10px;
} #div_digg .diggnum {
line-height: 1.5em !important;
} .diggit {
float: left;
width: 46px;
height: 52px;
background: url(/static/img/up.gif) no-repeat;
text-align: center;
cursor: pointer;
margin-top: 2px;
padding-top: 5px;
} .buryit {
float: right;
margin-left: 20px;
width: 46px;
height: 52px;
background: url(/static/img/down.gif) no-repeat;
text-align: center;
cursor: pointer;
margin-top: 2px;
padding-top: 5px;
} .clear {
clear: both;
} #div_digg .diggnum {
line-height: 1.5em !important;
} .diggword {
margin-top: 5px;
margin-left: 0;
font-size: 12px;
color: gray;
}
</style>
{% endblock %} {% block right_content %}
{# 文章及标题开始 #}
<h3>{{ article_obj.title }}</h3>
{{ article_obj.content|safe }}
{# 文章结束 #}
{# 点赞点踩开始 #}
<div class="clearfix">
<div id="div_digg">
<div class="diggit action">
<span class="diggnum" id="digg_count">{{ article_obj.up_num }}</span>
</div>
<div class="buryit action">
<span class="burynum" id="bury_count">{{ article_obj.down_num }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
</div>
</div>
</div>
{# 点赞点踩结束 #}
{# 评论楼开始 #}
<div><h4>评论</h4></div>
{% for comment in comment_list %}
<hr>
<div>
<span>#{{ forloop.counter }}楼&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span><span class="glyphicon glyphicon-time"></span>&nbsp;{{ comment.comment_time|date:'Y-m-d' }}&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span><span class="glyphicon glyphicon-user"></span>&nbsp;<a href="/{{ comment.user }}/">{{ comment.user }}</a></span>
<span class="pull-right reply " id="id_reply" username="{{ comment.user.username }}" comment_id="{{ comment.pk }}"><span class="glyphicon glyphicon-comment"></span>&nbsp;<a >回复</a></span>
</div>
<div> {% if comment.parent %}
<div>@{{ comment.parent.user.username }}</div>
{% endif %}
<div>{{ comment.content }}</div>
</div>
{% endfor %}
<div class="linshi_comment"></div> {# 评论楼结束 #}
{# 评论输入 开始 #}
<hr>
<div><span class="glyphicon glyphicon-comment"></span>&nbsp;&nbsp;&nbsp;发表评论</div> <div style="margin-top: 20px">
<span class="glyphicon glyphicon-user"></span>
<span>&nbsp;&nbsp;&nbsp;昵称:&nbsp;&nbsp;&nbsp;{{ request.user.username }}</span>
</div>
<div style="margin-top: 20px">
<span>评论内容:</span>
</div>
<div>
<textarea name="comment" id="id_comment" cols="60" rows="10"></textarea> </div>
<button class="btn btn-primary" id="id_submit_comment" style="margin-left: 400px; margin-top: 20px">提交</button> {# 评论输入结束 #}
{% endblock %} {% block js %}
<script>
// 点赞点踩 点击事件绑定
$('.action').click(function () {
let isUp = $(this).hasClass('diggit');
let $info = $('#digg_tips');
let $span = $(this).children();
$.ajax({
url: "/up_or_down/",
type: 'post',
data: {
'article_id':{{ article_obj.pk }},
'is_up': isUp,
'csrfmiddlewaretoken': '{{ csrf_token }}',
},
success: function (data) {
if (data.code == 200) {
console.log(data);
$info.html(data.msg);
//将span标签内的文本加1
$span.text(Number($span.text() + 1))
}
else {
$info.html(data.msg)
}
}
})
});
//{#评论js开始#}
// 先定义一个全局的 parent
let parentId='';
$('#id_submit_comment').click(function () {
// 获取textarea 文本内容
let $comment_content = $('#id_comment').val();
//判断parentId 是否有值,有值则进行切分
if (parentId){
// 获取切分的索引(切分的时候 顾头不顾尾,所以需要加1)
let indexVal = $comment_content.indexOf('\n')+1;
$comment_content=$comment_content.slice(indexVal);
}
// 发送ajax请求
$.ajax({
url: '/comment/',
type: 'post',
data: {
'article_id': '{{ article_id }}',
'comment_content': $comment_content,
'csrfmiddlewaretoken': '{{ csrf_token }}',
'parent_id': parentId
},
success: function (data) {
// 将新的评论临时渲染到前端页面
if (data.code == 100) {
let userName = '{{ request.user.username }}';
let commentConent = $comment_content;
//此处用的是前端的模板语言的替换
let tempStr = `
<div>
<hr>
<span><span class="glyphicon glyphicon-user"></span>&nbsp;<a href="/${userName}/">${userName}</a></span>
<p>${commentConent}</p>
</div>
`;
// 查找url标签,添加子元素
$('.linshi_comment').append(tempStr);
// 将textarea文本框清空
$('#id_comment').val('');
}
}
}) });
// 回复父评论信息
$('.reply').click(function () {
// 把你想评论的那条评论的任命自动添加到 textarea 文本中去
let pUserName=$(this).attr('username');
let pCommentId=$(this).attr('comment_id');
// 自动换行
$('#id_comment').val('@'+pUserName+'\n');
// 聚焦到评论文本框
$('#id_comment').focus();
//给parent_id 赋值
parentId=pCommentId;
});
</script>
{% endblock %}

博客详情页后端视图函数

# 将博客文章内容 以及评论的列表传导前端

# url.py 中的对应路由
url(r'^(?P<username>\w+)/article/(?P<article_id>\d+)',views.article_detail) # views.py
def article_detail(request, username, article_id):
# 从数据库中查找文章对象
article_obj = models.Article.objects.filter(pk=article_id).first()
# 查找当前用户对象
user_obj = models.UserInfo.objects.filter(username=username).first()
# 查找评论的queryset对象
comment_list= models.Comment.objects.filter(article_id=article_id)
return render(request, 'article_detail.html', locals()) # 评论 视图函数 路由
url('/comment/',views.comment) # views.py
def comment(request):
back_dic = {'code': 100, 'msg': ''}
if request.is_ajax():
article_id = request.POST.get('article_id')
comment_content = request.POST.get('comment_content')
parent_id = request.POST.get('parent_id')
print('article_id', article_id)
print('comment', comment_content)
# 1.先校验当前用户是否已经登录
if request.user.is_authenticated():
# 开启事务操作 // from django.db import transaction
with transaction.atomic():
# 1.在文章表中将普通字段加1
models.Article.objects.filter(pk=article_id).update(comment_num=F('comment_num') + 1)
# 2.在评论表中将存储真正的数据
models.Comment.objects.create(article_id=article_id, user=request.user, content=comment_content,parent_id=parent_id)
back_dic['msg'] = '评论成功'
else:
back_dic['code'] = 101
back_dic['msg'] = '请先登录'
return JsonResponse(back_dic)

BBS之文章详情页搭建的更多相关文章

  1. BBS项目分布搭建三(个人站点时间归档补充,实现侧边栏跳转、无线级分类、实现文章详情页展示功能)

    BBS项目分布搭建三(个人站点时间归档补充,) 1. 个人站点时间归档 """ settings.py设置最好更改以下: LANGUAGE_CODE = 'zh-hans ...

  2. thinkPHP中的文章详情页实现“上一篇下一篇”功能经验分享

    前段时间在公司中接触到了用thinkPHP搭建的项目,其中涉及到了文章详情页上一篇下一篇翻页的功能实现效果. 因为刚接触这套框架和PHP,所以整理一下实现该功能的经验方法. 如果有不到位的地方,欢迎指 ...

  3. python 全栈开发,Day81(博客系统个人主页,文章详情页)

    一.个人主页 随笔分类 需求:查询当前站点每一个分类的名称以及对应的文章数 完成这个需求,就可以展示左侧的分类 它需要利用分组查询,那么必须要会基于双下划线的查询. 基于双下划线的查询,简单来讲,就是 ...

  4. django博客项目8:文章详情页

    首页展示的是所有文章的列表,当用户看到感兴趣的文章时,他点击文章的标题或者继续阅读的按钮,应该跳转到文章的详情页面来阅读文章的详细内容.现在让我们来开发博客的详情页面,有了前面的基础,开发流程都是一样 ...

  5. HelloDjango 第 08 篇:开发博客文章详情页

    作者:HelloGitHub-追梦人物 文中涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 首页展示的是所有文章的列表,当用户看到感兴趣的文章时,他点击文章的标题或者继续阅读的按 ...

  6. dedecms5.7的文章详情页页面标题加载指定txt文本的随机关键字

    dedecms5.7的文章详情页加载指定txt文本的随机关键字 1 实现代码如下 {dede:name runphp='yes'} $file_path = "../test.txt&quo ...

  7. Django:文章详情页面评论功能需要登录后才能使用,登录后自动返回到文章详情页

    背景: 文章详情页正在查看文章,想评论一下写的不错,但是需要先登录才能.页面长这个样子: 方案: 1.点击登录链接时,将该页面的URL传递到登录视图中 request.path获取的是当前页面的相对路 ...

  8. BBS论坛 文章详情、点赞、评论

    六.文章详情.点赞.评论 文章详情页面: def article_detail(request, username, article_id): # user_obj = models.UserInfo ...

  9. 安卓开发——WebView+Recyclerview文章详情页,解决高度问题

    安卓开发--WebView+Recyclerview文章详情页,解决高度问题 最近在写一个APP时,需要显示文章详情页,准备使用WebView和RecyclerView实现上面文章,下面评论.出现了W ...

随机推荐

  1. Spring Boot 知识笔记(servlet、监听器、拦截器)

    一.通过注解自定义servlet package net.Eleven.demo.servlet; import javax.servlet.ServletException; import java ...

  2. 构建一个给爬虫使用的代理IP池

    做网络爬虫时,一般对代理IP的需求量比较大.因为在爬取网站信息的过程中,很多网站做了反爬虫策略,可能会对每个IP做频次控制.这样我们在爬取网站时就需要很多代理IP. 代理IP的获取,可以从以下几个途径 ...

  3. node.js 路由详解

    路由的基本使用 第一步:获取url跟目录下的字符 var http = require('http'); var url = require('url') http.createServer(func ...

  4. Kafka Offset Monitor页面显示空白

    下载包:https://github.com/Morningstar/kafka-offset-monitor.git 解决:jar包内\KafkaOffsetMonitor-assembly-0.2 ...

  5. ASP.Net Core使用分布式缓存Redis从入门到实战演练

    一.课程介绍 人生苦短,我用.NET Core!缓存在很多情况下需要用到,合理利用缓存可以一方面可以提高程序的响应速度,同时可以减少对特定资源访问的压力.  所以经常要用到且不会频繁改变且被用户共享的 ...

  6. 【Qt开发】Qt5.9安装

    Qt5.9安装包整合了全部资源,包括所有可选的不同版本及编译器,不用再单独下载,虽然大了点,但方便了很多.有时可能需要用VS搭配Qt来使用,但有时又想用QtCreator+mingw or QtCre ...

  7. Linux桌面环境

    早期的 Linux 系统都是不带界面的,只能通过命令来管理,比如运行程序.编辑文档.删除文件等.所以,要想熟练使用 Linux,就必须记忆很多命令. 后来随着 Windows 的普及,计算机界面变得越 ...

  8. AJAX -------------- 如何使用ajax

    AJAX  即“Asynchronous JavaScript and XML”(异步的JavaScript 与 XML技术 ),指的是一套综合了多项技术的浏览器端网页开发技术. 所谓为的异步交互:指 ...

  9. vs中使用tfs创建项目

    1.打开“Team Explorer”,点击“Home”,选择"Project"->"New Team Project",操作如下图: 2.输入项目名称. ...

  10. [转帖]Centos7防火墙配置rich-rule实现IP端口限制访问

    Centos7防火墙配置rich-rule实现IP端口限制访问 2019-02-18 18:05:35 sunny05296 阅读数 2143  收藏 更多 分类专栏: Linux   版权声明:本文 ...