BBS论坛 文章详情、点赞、评论
六、文章详情、点赞、评论



文章详情页面:
def article_detail(request, username, article_id):
# user_obj = models.UserInfo.objects.filter(username=username)
article_obj = models.Article.objects.filter(pk=article_id).first()
blog = models.Blog.objects.filter(userinfo__username=username).first()
comment_list = models.Comment.objects.filter(article_id=article_id)
return render(request, 'article_detail.html', locals())
views.py 文章详情页
{% 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;
}
.diggit {
float: left;
width: 46px;
height: 52px;
background: url('/static/img/upup.gif') no-repeat;
text-align: center;
cursor: pointer;
margin-top: 2px;
padding-top: 5px;
}
#div_digg .diggnum {
line-height: 1.5em !important;
}
.diggnum {
font-size: 14px;
color: #075db3;
font-family: Verdana;
}
.buryit {
float: right;
margin-left: 20px;
width: 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;
}
.diggword {
margin-top: 5px;
margin-left: 0;
font-size: 12px;
color: gray;
}
</style>
{% endblock %}
{% block 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" style="color: red;"></div>
</div>
</div>
<hr>
{# --------------------评论内容部分 开始 ------------------- #}
<p>评论列表:</p>
<div class="form-group list-group">
{% for comment in comment_list %}
<div class="form-group"><span style="color: cornflowerblue">#{{ forloop.counter }}楼 </span>
{{ comment.create_time|date:'Y-m-d' }}
<a href="/{{ comment.user.username }}/">{{ comment.user.username }}</a>
<span class="pull-right reply" comment_id="{{ comment.pk }}" username={{ comment.user.username }}><a>回复</a></span>
<div>
{% if comment.parent %}
<p>@ {{ comment.parent.user.username }}</p>
{% endif %}
<p style="color: darkgray"> {{ comment.content }}</p>
<hr>
</div>
</div>
{% endfor %}
</div>
{# --------------------评论内容部分 结束 ------------------- #}
{% if request.user.is_authenticated %}
{# -----------------------------评论部分 开始 ---------------------- #}
<div>
<p><span class="glyphicon glyphicon-comment"></span>发表评论</p>
<p>
<span>昵称:<span class="glyphicon glyphicon-user"></span></span>
<input type="text" value="{{ request.user.username }}" disabled>
</p>
<p>评论内容:</p>
<textarea name="" cols="80" rows="10" id="id_comment"></textarea>
<p>
<button class="btn btn-primary" id="id_submit">提交评论</button>
</p>
<br><br><br>
</div>
{# ------------------------------评论部分 结束 ---------------------- #}
{% endif %}
{% endblock %}
{% block js %}
<script>
console.log("this is script!");
// 点赞点踩
$('.action').click(function () {
{#alert($(this).hasClass('diggit')) 利用类操作判断是否有某一个类属性从而区分是点赞还是点踩#}
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) {
$info.html(data.msg);
// 将span标签内部的文本数字加1
$span.text(Number($span.text()) + 1)
} else {
$info.html(data.msg)
}
}
})
});
let parentId = '';
// 提交评论
$('#id_submit').click(function () {
console.log("this is 提交数据!");
let sub_content = $('#id_comment').val();
if (sub_content == ''){
alert("评论不能为空!")
}else{
console.log('this is sub_content:', sub_content);
if (parentId){
let indexVal = sub_content.indexOf('\n') +1;
sub_content = sub_content.slice(indexVal);
console.log(sub_content)
}
// 分析: 将评论提交到后端,需要传 文章id、评论内容,评论人的id
$.ajax({
url: '/comment/',
type: 'post',
data: {
'article_id': '{{ article_id }}',
'content': sub_content,
'csrfmiddlewaretoken': '{{ csrf_token }}',
'parentId': parentId,
},
success: function (data) {
if (data.code == 100) {
let userName = '{{ request.user.username }}';
let content = sub_content;
let tempStr = `
<div>
<p class="form-group"><span style="color: cornflowerblue">
<a href="/${userName}/">${userName}</a>
</p>
<p style="color: darkgray"> ${content}</p>
<hr>
</div>
`;
$(".list-group").append(tempStr);
// 将textarea框中的内容清空
$('#id_comment').val('');
// 将全局的parentId清空
parentId = ''
}
}
})
}
});
// 回复按钮逻辑代码
$('.reply').click(function () {
// 1.把你想评论的那条评论所属者的名字添加到textarea中(@+用户名) 如何获取评论人名
let pUserName = $(this).attr('username');
let pCommentId = $(this).attr('comment_id');
// 2.自动换行
$('#id_comment').val('@'+pUserName+'\n');
// 3.textarea自动聚焦
$('#id_comment').focus();
// 4.将全局的parentId赋值
parentId = pCommentId;
});
</script>
{% endblock %}
article_detail.html
def up_or_down(request):
back_dic = {'code': 100, 'msg': ''}
if request.is_ajax():
is_up = request.POST.get('is_up')
is_up = json.loads(is_up) # 利用json模块反序列称后端python布尔值类型
article_id = request.POST.get('article_id') # 1.判断用户是否登录
if request.user.is_authenticated():
# 2.判断文章是否是当前用户写的
article_obj = models.Article.objects.filter(pk=article_id).first()
if not article_obj.blog.userinfo.pk == request.user.id:
# 3.判断当前用户是否对该文章点赞或点踩了
res = models.UpAndDown.objects.filter(user=request.user, article=article_obj)
if not res:
# 4.需要在两张表里面修改数据
# 先修改普通字段的数据
if is_up:
# 点赞
models.Article.objects.filter(pk=article_id).update(up_num=F('up_num') + 1)
back_dic['msg'] = '点赞成功'
else:
# 点踩
models.Article.objects.filter(pk=article_id).update(down_num=F('down_num') + 1)
back_dic['msg'] = '点踩成功'
# 最后修改UpAndDown表数据
models.UpAndDown.objects.create(user=request.user, article=article_obj, is_up=is_up)
back_dic['code'] = 200
else:
back_dic['code'] = 201
back_dic['msg'] = '你已经点过了'
else:
back_dic['code'] = 202
back_dic['msg'] = '你个臭不要脸的不能点自己的'
else:
back_dic['code'] = 203
back_dic['msg'] = mark_safe('请先<a href="/login/">登录</a>')
return JsonResponse(back_dic)
views.py 点赞点踩
def comment(request):
back_dic = {'code': 100, 'msg': ''}
if request.is_ajax():
# 获取前端发过来的数据
# print("this is comment!")
article_id = request.POST.get('article_id')
# print(article_id)
content = request.POST.get('content')
# print(content)
parent_id = request.POST.get('parentId')
# print(parent_id)
if request.user.is_authenticated():
# print("已经登录,正要去写评论入库")
with transaction.atomic():
# 在文章表中普通的评论字段加1
models.Article.objects.filter(pk=article_id).update(comment_num=F('comment_num') + 1)
# 再在评论表中将评论的信息存储
models.Comment.objects.create(user=request.user, article_id=article_id, content=content,
parent_id=parent_id)
back_dic['msg'] = '评论成功!'
else:
back_dic['code'] = 101
back_dic['msg'] = '请想登录!'
return JsonResponse(back_dic)
views.py 评论
BBS论坛 文章详情、点赞、评论的更多相关文章
- BBS之文章详情页搭建
博客评论相关 博客文章详情页搭建 {% extends 'base.html' %} {% block css %} <style> #div_digg { float: right; m ...
- Django:文章详情页面评论功能需要登录后才能使用,登录后自动返回到文章详情页
背景: 文章详情页正在查看文章,想评论一下写的不错,但是需要先登录才能.页面长这个样子: 方案: 1.点击登录链接时,将该页面的URL传递到登录视图中 request.path获取的是当前页面的相对路 ...
- $Django 站点:样式--文章--分类文章--文章详情--文章评论点赞--文章评论点赞统计(数据库优化)
<h3>个人站点下的</h3> 知识点 url (r'(?P<username>\w+)/p/(?P<id>\d+)', xiangxi,name='x ...
- BBS项目分布搭建三(个人站点时间归档补充,实现侧边栏跳转、无线级分类、实现文章详情页展示功能)
BBS项目分布搭建三(个人站点时间归档补充,) 1. 个人站点时间归档 """ settings.py设置最好更改以下: LANGUAGE_CODE = 'zh-hans ...
- Python之路【第十八篇】Django小项目简单BBS论坛部分内容知识点
开发一个简单的BBS论坛 项目需求: 整体参考“抽屉新热榜” + “虎嗅网” 实现不同论坛版块 帖子列表展示 帖子评论数.点赞数展示 在线用户展示 允许登录用户发贴.评论.点赞 允许上传文件 帖子可被 ...
- python 学习笔记二十 django项目bbs论坛
项目:开发一个简单的BBS论坛 需求: 整体参考“抽屉新热榜” + “虎嗅网” 实现不同论坛版块 帖子列表展示 帖子评论数.点赞数展示 在线用户展示 允许登录用户发贴.评论.点赞 允许上传文件 帖子可 ...
- python第一百三十天 ---简单的BBS论坛
简单的BBS论坛 实现功能 git仓库地址:https://github.com/uge3/BBS 1.整体参考“抽屉新热榜” + “博客园” 2.实现不同论坛版块 3.帖子列表展示 4.个人博客主页 ...
- Django小项目简单BBS论坛
开发一个简单的BBS论坛 项目需求: 1 整体参考"抽屉新热榜" + "虎嗅网" 2 实现不同论坛版块 3 帖子列表展示 4 帖子评论数.点赞数展示 5 在线用 ...
- Python开发一个简单的BBS论坛
项目:开发一个简单的BBS论坛 需求: 整体参考“抽屉新热榜” + “虎嗅网” 实现不同论坛版块 帖子列表展示 帖子评论数.点赞数展示 在线用户展示 允许登录用户发贴.评论.点赞 允许上传文件 帖子可 ...
随机推荐
- PAT程序设计
VS2013中自行对齐的快捷键操作: CTRL+K+F 1.定义二维数组 ]=]; 2.绝对值函数 int abs(int i) 返回整型参数i的绝对值 double cabs(struct comp ...
- OC开发系列-内存管理
概述 移动设备的内存极其有限,每个app所有占用的内存是有限的.当app所占用的内存比较多时,系统会发出内存警告,这时得回收一些不需要再使用的内存空间. 任何集成了NSObject的对象都需要手动进行 ...
- postgresql like 中的转义
select * from tb_org where char_length(xdm)>8 and xdm not like '%*_%' ESCAPE '*' ESCAPE 后面的 * 是转 ...
- Linux 登录、注销与关机
Linux 登录.注销与关机 这里主要学习的是命令行环境下的相关操作. 一.登录 Linux 默认的情况下会提供六个终端来让用户登录,切换的方式为使用:[Ctrl + Alt + F1 ~ F6]的组 ...
- 手机作为蓝牙音频源连接到Linux时,如何通过音量键调节传入的音量大小
背景一: 我们知道,把手机作为音频源通过蓝牙连接到电脑,就可以把手机的声音转移到电脑上. 背景二: 我喜欢带着耳机用我的Linux本刷youtube,也喜欢用我的iPhone听音乐.为了同时做这两件事 ...
- Java中如何获取到线程dump文件
死循环.死锁.阻塞.页面打开慢等问题,打线程dump是最好的解决问题的途径.所谓线程dump也就是线程堆栈,获取到线程堆栈有两步: (1)获取到线程的pid,可以通过使用jps命令,在Linux环境下 ...
- JavaWeb开发之二《JSP + Tomcat的第一个程序“Hello World”》
搬以前写的博客[2014-12-10 22:41] 前一篇博客讲了Tomcat环境搭建,于是开始第一个“Hello JSP”程序. 服务器环境搭建好之后,我们开始写自己的网站,这里简单的写一个没有后台 ...
- leetcood学习笔记-27-移除元素
题目: 第一次提交: class Solution: def removeElement(self, nums, val: int) -> int: for i in range(len(num ...
- 深入理解Magento-第九章-修改、扩展、重写Magento代码
(博主提示:本章应该不是原作者的第九章,仅作补充和参考) 作为一个开发者的你,肯定要修改Magento代码去适应你的业务需求,但是在很多时候我们不希望修改Magento的核心代码,这里有很多原因,例如 ...
- Delphi中点击网页弹出的Alert对话框的确定按钮
思路: 使用Windows API函数遍历窗口,查找指定标题的窗口,然后从该窗口查找确定按钮,向该按钮发送鼠标消息进行模拟点击.由于IE8由Alert弹出的网页对话框的标题是“来自网页的消息”,而IE ...