bbs项目day04---文章子评论业务逻辑,后台管理页面搭建,添加文章页面搭建,富文本编辑器,添加文章功能简易版本,添加文章功能优化
昨日内容回顾
- 个人站点侧边栏筛选功能
1.研究侧边栏路由规律
2.初步指定三个路由
站点名称\category\分类主键值
站点名称\tag\标签主键值
站点名称\archive\年-月
3.路由优化设计
正则匹配
4.由于筛选还是基于个人站点 所以多个路由使用相同的视图函数
通过视图函数接收的实参个数不同从而区分不同的业务逻辑
5.根据条件二次过滤文章数据
正反向查询、神奇的双下划线查询
- 侧边栏inclusion_tag制作
1.侧边栏很多页面都需要使用 并且还需要传参才可以加载出来
2.干脆制作成inclusion_tag调用 从而节省代码
3.自定义操作固定步骤(模板层相关知识)
- 点赞点踩样式搭建
直接拷贝博客园相关html和css即可
ps:图片防盗链技术
- 点赞点踩功能完善
1.前端页面给点赞点踩图标绑定点击事件
通过标签class值的不同区分是赞还是踩
发送ajax请求携带文章主键值、点赞点踩...
2.后端业务逻辑
校验用户是否登录、校验当前用户是否是文章作者、校验当前用户是否已经点过、完成数据库操作(注意普通字段数据更新)
ps:注意前端发送过来的js类型的布尔值需要自己处理成python布尔值
3.前端展示优化
信息提示、数字动态变化
ps:针对标签文本需要做类型转换 否则默认是字符串拼接
- 文章评论样式搭建
最简易的几个标签
获取用户输入的textarea以及一个提交按钮
- 文章根评论业务逻辑
1.给提交按钮绑定点击事件
2.发送ajax请求
携带评论内容、文章主键
3.后端直接获取数据并写入数据库
还是得注意文章表中的普通字段
ps:很多业务逻辑可能需要执行多条ORM语句 这个时候为了保证数据的完整可以采用事务操作(回想ORM事务的三种操作方式)
.
.
.
.
.
今日内容概要
- 文章子评论业务逻辑
- 后台管理页面搭建
- 添加文章页面搭建
- 富文本编辑器
- 添加文章功能简易版本
- 添加文章功能优化
今日内容详细
文章评论业务完善
提交评论后会出现的情况:
评论框里面的内容会清空 然后页面会有一个临时评论样式出现 页面刷新才会出现评论楼样式
功能实现:原提交评论的点击事件里面的ajax的回调函数里面:回调函数里面先还是查找到评论框textarea标签,然后清空掉内容$('#comment111').val('') 再动态创建标签,并添加到临时评论楼中
复制上面评论楼里面的li标签代码,
let tempComment = `
<li class="list-group-item">
<span><a class="glyphicon glyphicon-comment" href="/app01/{{ comment_obj.user.username }}/">评论人:{{ comment_obj.user.username }}</a></span>
<p>
${commentInfo}
</p>
</li>
`
查找评论楼的ul标签然后将上述的模板字符串添加到ul标签里面的最后,并将字符串自动转化为标签
$('.list-group').append(tempComment)
.
.
.
.
研究子评论特性:
研究子评论特性:
1. 每个评论右侧都应该有回复按钮 点击就可以填写子评论
2. 点击回复按钮具体动作:自动聚焦到评论框中,且评论框中自动添加@+评论的人名并换行
如何区分不同的回复按钮所对应的用户名?
利用标签可以自定义属性直接携带对应的评论用户名即可
<a href="" class="reply111" username="{{ comment_obj.user.username }}">回复</a>
let targetUserName = $(this).attr('username')
或者笨一点,找到有写用户名的标签然后拿该标签的内容用.text()拿
$('#comment111').val('@' + targetUserName + '\n').focus()
# 把@评论的人名\n 添加到评论框标签的内容里面去,并聚焦到评论框里面去
----------------------------------------------------
提交根评论和子评论点击的是同一个提交评论按钮, 两者的区别与联系是什么?
其实根评论和子评论的唯一区别就是:是否有父评论的主键值
如何区分不同的回复按钮所对应的父评论主键值?
还是利用标签可以自定义属性,直接携带对应的评论主键值即可
----------------------------------------------------
所以根评论与子评论的唯一区别就是parent_id字段有没有值,所以也就是说点击评论按钮,触发点击事件,ajax发送的评论数据里面必须要有parent_id对应的信息,无论是null还是一个值
所以在点击回复按钮的点击事件里面,我们要获取该条根评论的comment_id,作为子评论的parent_id
但是我们发表跟评论与发表子评论都是要在textarea标签里面输入评论内容,然后点击发表评论按钮,通过点击事件利用ajax将评论数据发给后端,所以要在全局先定义一个
let parentId = null
回复按钮的点击事件里ajax发送的数据里面加一个键值对
'parent_id':parentId
然后在回复按钮的点击事件里面,通过修改修改全局变量parentId = $(this).attr('comment_id');
这样点击回复按钮触发点击事件后,聚焦到评论框里面去,写入评论内容,再点击提交评论按钮,触发提交评论按钮的点击事件,然后利用ajax将数据发给后端,这样如果是根评论,在提交评论按钮的点击事件里面拿到的parentId就是一个空,但是如果先点击的回复按钮,在回复按钮的点击事件里面,将parentId改成了要回复的这条根评论的主键值!!!(前端没有局部不能改全局变量名的值的说法,和后端有点区别)
-----------------------------------------------------
根评论和子评论的唯一区别就是是否有父评论的主键值。
根评论的parent_id为null,子评论的parent_id是对应的根评论的主键值!!!
.
.
.
子评论功能完善
-----------------------------------------------
问题一: 点击回复按钮发送子评论,页面不刷新的情况下,后续的评论全部成了子评论!!!
原因是全局变量parentId没有清空导致的 每次提交评论后,都应该在前端的发送ajax请求代码的后面,清空一下parentId对应的值。
------------------------------------------------
问题二: 针对子评论内中的 @根评论用户名换行 ,理论上不属于用户评论的内容,不应该记录到数据库
前端可以剔除 也可以在后端剔除
在前端剔除方法:在发送ajax请求前,先判断parentId有没有值,来确定是不是子评论,如果是子评论,想办法处理掉前缀内容
if (parentId) {commentInfo = commentInfo.slice(commentInfo.indexOf('\n') + 1)}
在后端剔除方法:
if parentId:
parentId.split('\n')[-1]
------------------------------------------------
问题三: 针对子评论的渲染 应该动态判断是否是子评论 如果是应该加上评论的目标用户名
因为现在我们保证了写进数据库里面的子评论内容没有了@用户名加换行符了,但是这也导致了该子评论渲染在评论楼里面的时候,用户看不出来该子评论是哪个根评论的子评论了,虽然我们在后台看文章表能看出来,但是用户看不出来啊,所以还需要在前端判断一下该评论是不是子评论,如果是还要在评论内容的上面在渲染出@根评论用户名的标签出来才比较合理
很简单在原评论内容的标签上面来个判断即可
<p>
{% if comment_obj.parent_id %}
@{{ comment_obj.parent.user.username }}
{% endif %}
</p>
<p>
{{ comment_obj.content }}
</p>
--------------------------------
同理 临时评论楼的渲染评论内容的时候,可以这样玩:
let commentInfo = $('#comment111').val();
let oldCommentInfo = $('#comment111').val();
两个变量名同时绑一个标签的的val值,但是commentInfo变量名后续继续进行切割操作切掉对应的@用户名换行符,然后给ajax发送到后端
但是oldCommentInfo变量名却给ajax的回调函数,用来渲染临时的评论楼标签里面的内容,这样临时评论楼里面也能看出是给哪个根评论评论的了!!!
--------------------------------
实际上问题二与问题三,可以都不处理也行。这两个问题属于无关紧要的小优化
-------------------------------------------------
ps:针对评论的渲染也可以分页 也可以做根评论与子评论的集合操作(分类)
.
.
.
.
后台管理
先把路由与视图函数名对应好,然后在主页的导航条里面的更多操作里面把后台管理的a标签路由配一下,然后开始写视图函数与前端页面!!!
1.模仿博客园后台访问直接展示所有文章
面包屑排布的代码里面来一个
可以参考homePage页面,导航条模态框以及模态框对应的js代码等都可以直接复制过来,正真要改的地方就只有,内容区要改一下,整体按栅格系统2,10比例,home页面的内容区左边是广告栏现在改成博客园后台的分类区,右边变成一个面包屑排布
面包屑头就是: 随笔、文章、日记、评论等一个个的选项
面包屑体就是: 每一个选项对应的需要的样式
------------------------------------------------
2.后台管理页面需要多次被当做模板页面使用
如果该页面也是继承其他页面那么无法二次被继承使用,
所以需要我们 单独编写一个后台管理的模板页面
我们只需要把面包屑体里面的每一个选项对应的样式区的代码用
{ block XXX }
{% endblock %}
包裹起来,这样当我们点后台页面的左边的添加文字,添加分类,这些按钮的时候,要跳转的页面就直接继承后台管理的模板页面,然后只改对应的
{ block XXX }
{% endblock %}
区域代码就可以了!!!
.
.
右边区域 面包屑排布的js代码模板!!!
.
.
.
添加文章
1.页面简易搭建
利用form表单,提交数据,主要就是后端先给前端提供该个人站点对象所拥有的分类列表与标签列表category_list,和tag_list
category_list = models.Category.objects.filter(site=site_obj)
tag_list = models.Tag.objects.filter(site=site_obj)
然后前端对这两个queryset进行for循环拿到每一个对象
添加文章的时候,分类是单选,所以用radio
标签是多选,所以用checkbox
其次注意选择框要有name与value选项
标题就用个input框type="text"
文章内容就用个textarea标签
最后搞个发布文章的按钮就行了!!!
-----------------------------------------------------
-----------------------------------------------------
2.文章内容区富文本编辑器的使用
课下可以自行查找更多的富文本编辑器使用
某一款富文本编辑器的官网
http://kindeditor.net/about.php
-----------------------------------------------------
-----------------------------------------------------
.
富文本编辑器相关操作
.
.
.
.
就是告诉我们textarea标签的id值要与富文本编辑器的这个js代码里面的括号里面查找的标签id一样
.
.
富文本编辑器就有了
.
编辑器初始化配置
.
.
每个单词就代表一个功能图标,如果嫌图标多了可以对应的删掉一些
.
resizeType 是控制编辑框的高度与宽度能不能动的!!
.
.
3.添加文章需要注意的问题
----------------------------------------------
文章简介不应该有标签存在
----------------------------------------------
文章内容不允许编辑script脚本(XSS攻击)
不允许用户编写<script>alert(123)</script>这种类型的标签的
因为如果用户写个无限次循环的js代码,页面直接就卡死了!!!
博客园就不支持我们编辑html源代码的时候,写script标签
所有的能够支持用户保存数据的网站,都有一个策略,要么直接把你写的<script>标签全部删掉,
因为用户没有资格在直接在编辑html源代码的内容里面写<script>标签,因为如果用户写个死循环,该文章一展示,就会把网站都搞崩掉了!!!
只能允许用户在博客园的设置里面写一些,针对网站页面的js脚本,不能写某一篇文章的js脚本,
实际上我们在博客园的文章内容区写的文本内容,实际上底层对应的是写的html代码
现在需求就是把标签剔除掉,只留文章内容作为文章简介,也就是文章简介不能简单的截取150个字符内容作为文章简介的
可以用正则来筛选出文本来,但是正则写起来就很烦,
解决办法: 涉及到html页面相关内容的处理,可以借助于爬虫相关模块bs4
----------------------------------------------
.
可以看到文章简介将标签的代码都算进去了,我实际上想要看到的只是标签里面的文本!!!
.
.
bs4模块下载
pip3.8 install bs4
可能会报需要信任源
pip3.8 install --user --index-url http://mirrors.aliyun.com/pypi/simple/ bs4 --trusted-host mirrors.aliyun.com
顺便要下一个该模块的解析器lxml模块(python自带的html也能用)
pip3.8 install --user --index-url http://mirrors.cloud.tencent.com/pypi/simple/ lxml --trusted-host mirrors.cloud.tencent.com
该模块的功能是支持解析页面的内容,也就是能够帮我们处理页面,比如说想拿页面上所有的标签、
拿页面上所有的字符串、都可以直接点方法直接拿.
.
.
.
作业
1.整理今日内容及博客
2.自行学习bs4模块其他功能
3.自行研究富文本编辑器使用
4.尝试完善添加文章功能
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)