BBS_02day:

展示个人所有文章:

def article_detail(request,username,article_id):
# 将文章查询出来
article_obj = models.Article.objects.filter(pk=article_id).first()
blog = article_obj.blog
# 还应该获取当前文章所有的评论信息
comment_list = models.Comment.objects.filter(article=article_obj)
if not article_obj: #没有则404
return render(request,'error.html')
return render(request,'article_detail.html',locals())

点赞,点彩功能:

import json
from django.db.models import F
from django.utils.safestring import mark_safe
def updown(request):
if request.is_ajax():
if request.method == 'POST':
back_dic = {'code':1000,'msg':''}
is_up = request.POST.get('is_up') # 是一个字符串格式的json数据
article_id = request.POST.get('article_id')
is_up = json.loads(is_up) # 将json格式的字符串数据转成python对应的数据类型
# print(is_up,type(is_up))
"""
点赞点踩业务逻辑
1.判断当前用户是否登录
2.当前这篇文章是否是当前用户自己写的
3.当前这篇文章用户是否已经点过
4.操作数据库 完成数据修改
1.点赞点踩添加数据的时候
2.文章表里面对应的普通字段也得修改
"""
# 1.判断当前用户是否登录
if request.user.is_authenticated():
# 2.当前这篇文章是否是当前用户自己写的
article_obj = models.Article.objects.filter(pk=article_id).first()
if not article_obj.blog.userinfo == request.user:
# 3.当前这篇文章用户是否已经点过
is_click = models.UpAndDown.objects.filter(user=request.user,article=article_obj).exists()
if not is_click:
# 操作数据库 完成数据修改
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'] = '点踩成功'
models.UpAndDown.objects.create(user=request.user,article=article_obj,is_up=is_up)
else:
back_dic['code'] = 2000
back_dic['msg'] = '你已经点过了不能在点了'
else:
back_dic['code'] = 3000
back_dic['msg'] = '你个臭不要脸的 不能给自己点' else:
back_dic['code'] = 4000
back_dic['msg'] = mark_safe('请先<a href="/login/">登录</a>') #后端直接与前端交互
return JsonResponse(back_dic)

评论功能:

from django.db import transaction

def comment(request):
if request.is_ajax():
if request.method == 'POST':
back_dic = {'code':1000,'msg':''}
article_id = request.POST.get('article_id')
content = request.POST.get('content')
# parent_id如果有值那么正常存储 如果没有值也无所谓就存空 也符合要求
parent_id = request.POST.get('parent_id')
with transaction.atomic():
models.Comment.objects.create(user=request.user,article_id=article_id,content=content,parent_id=parent_id)
models.Article.objects.filter(pk=article_id).update(comment_num = F('comment_num') + 1) #F(): 变量动态值的运算
back_dic['msg'] = '评论成功'
return JsonResponse(back_dic)

页面展示:

#article_detail.html

{% extends 'base.html' %}

{% block css %}
<style>
#div_digg {
float: right;
margin-bottom: 10px;
margin-right: 30px;
font-size: 12px;
width: 128px;
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;
} .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: #808080;
}
</style>
{% endblock %}
{% block content %}
<div>
<h2>{{ article_obj.title }}</h2>
{{ 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">
<span class="info" style="color: red"></span>
</div>
</div>
</div>
{# 点赞点踩样式结束 #} {# 评论楼渲染#}
<div>
<ul class="list-group">
{% for comment in comment_list %}
{# #15楼 2019-11-08 20:03 蔡彦辉的博客#}
<li class="list-group-item">
<span><a href="#">#{{ forloop.counter }}楼</a></span>
<span>{{ comment.create_time|date:'Y-m-d' }}</span>
<span><a href="/{{ comment.user.username }}/">{{ comment.user.username }}</a></span>
<span><a class="reply pull-right" username="{{ comment.user.username }}" comment_id="{{ comment.pk }}">回复</a></span>
<div>
{% if comment.parent %}
<p>@{{ comment.parent.user.username }}</p>
{% endif %}
{{ comment.content }}
</div>
</li>
{% endfor %}
</ul>
</div> {# 评论开始#}
{% if request.user.is_authenticated %}
<div>
<p>发表评论</p>
<p>
昵称:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50"
value="{{ request.user.username }}">
</p>
<p>评论内容:</p>
<p>
<textarea name="comment" id="id_comment" cols="60" rows="10"></textarea>
</p>
<button class="btn btn-primary" id="id_submit">提交评论</button>
</div>
{% else %}
<p><a href="{% url 'login' %}">登录</a>&nbsp;&nbsp;&nbsp;&nbsp;
<a href="{% url 'register' %}">注册</a></p> {% endif %} {# 评论结束#} </div> <script>
// 点赞点踩
$('.action').click(function () {
let isUp = $(this).hasClass('diggit');
let $target = $(this);
$.ajax({
url: '/up_down/',
type: 'post',
data: {
'csrfmiddlewaretoken': '{{ csrf_token }}',
'is_up': isUp,
'article_id': "{{ article_obj.pk }}"
},
success: function (data) {
if (data.code == 1000) {
// 给span标签渲染信息
$('.info').text(data.msg);
// 点赞或点踩成功之后 应该将前端的数字也加一
let $span = $target.children();
let oldNum = $span.text();
$span.text(Number(oldNum) + 1) // 转整型相加 不然就是字符串拼接了
} else {
$('.info').text(data.msg)
}
}
})
});
// 评论
// 提前定义一个全局变量parentId
let parentId = null;
$('#id_submit').click(function () {
// 判断全局的parentid是否有值 如果有 你应该将前面的@人名\n切除
let content = $('#id_comment').val();
if (parentId){
// 获取\n所在的索引值
let nIndex = content.indexOf('\n') + 1; // 索引顾头不顾尾 加一才能切到
// 按照nIndex切换文本内容
content = content.slice(nIndex) // 将nIndex之前的内容直接去除 保留之后的内容 } $.ajax({
url: '/comment/',
type: 'post',
data: {
'csrfmiddlewaretoken': '{{ csrf_token }}',
'content':content,
'article_id': '{{ article_obj.pk }}',
'parent_id':parentId
},
success: function (data) {
if (data.code == 1000){
// 临时渲染
let userName = '{{ request.user.username }}';
let content = $('#id_comment').val();
let tmp = `
<li class="list-group-item">
<span><span class="glyphicon glyphicon-comment"></span><a href="/${ userName}/">${userName}:</a></span>
<p>
${content}
</p>
</li> `;
// 将生成好的内容添加到ul标签内部
$('.list-group').append(tmp);
// 将评论框中的内容清空
$("#id_comment").val('');
// 将全局的parentid再制成空null
parentId = null;
}
}
})
});
// 点击回复按钮
$('.reply').on('click',function () {
// 如何获取想要评论的那条评论人的姓名
let userName = $(this).attr('username');
// 如何获取要评论的那条评论的主键值
parentId = $(this).attr('comment_id'); // 赋值给全局的parentId
// 回复按钮的三件事
let headerMsg = '@' + userName + '\n';
$('#id_comment').val(headerMsg);
$('#id_comment').focus(); // 让评论框自动聚焦 })
</script>
{% endblock %}

BBS_02day的更多相关文章

随机推荐

  1. pywinauto教程2

    一.环境安装 1.命令行安装方法 pip install pywinauto==0.6.7 2.手动安装方法 安装包下载链接:pyWin32: python调用windows api的库https:/ ...

  2. [线段树]Luogu P3372 线段树 1【模板】

    #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #d ...

  3. vue-cli安装以及创建一个简单的项目(二)(vuex使用、发行一个简单的app)

    1.vuex的使用 vuex是vue的状态管理中心,vuex来保存我们需要管理的状态值,值一旦被修改,所有引用该值的地方就会自动更新,常用于: 1.多个视图依赖同一状态(l例:菜单导航) 2.来自不同 ...

  4. pytz库时区的坑(转)

    add by zhj: 推荐使用标准库中的dateutil代替pytz 原文:https://www.hongweipeng.com/index.php/archives/1803/ 起步 在djan ...

  5. 【04】Nginx:rewrite / if / return / set 和变量

    写在前面的话 我们前面已经谈了编译安装,基本语法,日志处理,location 匹配,root / alias 的不同效果.这里我们主要谈谈 rewrite(重写)功能,顺便说说 nginx 中自带的变 ...

  6. SQL Server中使用SQL语句关闭数据库连接和删除数据库文件

    有时候我们想用DROP DATABASE语句删除数据库和数据库文件,会删不掉,因为有其他人正在使用要删除的数据库,这里有一个方法可以强制断开其它数据库连接,再删除数据库. 假如我们要删除的数据库是[T ...

  7. "初识".Net Winfom

    对于“初识”Winform中 初识这两个字的涵义,实际上之前我一直接触的是B/S方面的知识和开发,虽然说不上是熟练,但是大部分时间都是花在B/S上了,例如MVC,如今要从B/S转到C/S了,说实话心里 ...

  8. jQuery 杂项方法大全

    下表列出了所有jQuery 杂项方法: 方法 描述 data() 将数据附加到选定元素或从中获取数据 get() 获取选择器匹配的DOM元素 index() 从匹配的元素中搜索给定的元素 $.noCo ...

  9. 【入门篇】前端框架Vue.js知识介绍

    一.Vue.js介绍 1.什么是MVVM? MVVM(Model-View-ViewModel)是一种软件架构设计模式,它源于MVC(Model-View-Controller)模式,它是一种思想,一 ...

  10. filebeat + ELK 部署篇

    ELK Stack Elasticsearch:分布式搜索和分析引擎,具有高可伸缩.高可靠和易管理等特点.基于 Apache Lucene 构建,能对大容量的数据进行接近实时的存储.搜索和分析操作.通 ...