新增文章富文本编辑器
富文本编辑器
- 类似于 word操作 插入图片。。 kindedit
- 类似于 md 操作
# 官网:http://kindeditor.net/doc.php
- 下载压缩包---》放在static文件夹下
- 新增文章页面:
<textarea name="content" id="editor_id" cols="200" rows="10" class="form-control"></textarea>
{% block script %}
<script charset="utf-8" src="/static/kindeditor/kindeditor-all.js"></script>
<script charset="utf-8" src="/static/kindeditor/lang/zh-CN.js"></script>
<script>
KindEditor.ready(function (K) {
window.editor = K.create('#editor_id', {
width: '100%',
height: '600px',
resizeType:0
});
});
</script>
{% endblock %}
去除xss攻击
Beautifulsoup4 爬虫解析模块--》用来删除html标签中得某些标签
#pip3 install Beautifulsoup4
# html 特殊字符
-页面中看到<script> 其实是 $lt; script $gt;
-真正的<script> 是看不到的,被渲染
-django 模板默认是处理的xss攻击的----》就是对 特殊字符做替换
-如果 |safe 就不替换了---》一定要保证 |safe 字符串是没问题的
# 如果在富文本编辑器中写代码,不存在问题---》富文本编辑器做了替换
# 如果在 源码中直接放标签会有问题
# 后端 bs4模块-->删除script标签
soup = BeautifulSoup(content) # html标签样子
list_script = soup.find_all('script') # 找到所有script标签,不会包含 用户的代码 已经被特殊字符替换了
for l in list_script:
l .decompose() # 把这个标签从 html中删除
content = str(soup) #带标签---》存带标签的
desc = soup.text[0:70] # 取摘要,只要文字,不要标签
# 真正的去除xss攻击
< script > ---> 替换 $lt; $gt; 存到数据库中
$lt; script $gt; $lt;/ script $gt;
富文本编辑器上传图片
后端
from django.conf import settings
def upload_file(request):
file = request.FILES.get('myfile')
path = os.path.join(settings.MEDIA_ROOT, 'img')
with open('%s/%s' % (path, file.name), 'wb') as f:
for line in file:
f.write(line)
return JsonResponse({
"error": 0,
"url": "/media/img/%s" % file.name
})
前端
KindEditor.ready(function (K) {
window.editor = K.create('#editor_id', {
width: '100%',
height: '600px',
resizeType: 0,
uploadJson: '/upload_file/',
filePostName: 'myfile',
extraFileUploadParams: {
csrfmiddlewaretoken: '{{ csrf_token }}'
}
});
});
# 注释掉中间件
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
修文章
前端
{% extends 'backend/backend_base.html' %}
{% block articles %}
<div>
<h3 class="text-center">添加文章</h3>
<form method="post" action="/update_article/?id={{ article.id }}">
{% csrf_token %}
<input type="hidden" name="id" value="{{ article.id }}">
<div class="form-group">
<label for="">标题</label>
<input type="text" class="form-control" name="title" value="{{ article.title }}">
</div>
<div class="form-group">
<label for="">内容</label>
<textarea name="content" id="editor_id" cols="200" rows="10" class="form-control">
{{ article.content }}
</textarea>
</div>
<div class="form-group">
<label for="">分类</label>
<select class="form-control" name="category">
{% for category in category_list %}
{% if article_category.id == category.id %}
<option value="{{ category.id }}" selected>{{ category.name }}</option>
{% else %}
<option value="{{ category.id }}">{{ category.name }}</option>
{% endif %}
{% endfor %}
</select>
</div>
<div class="form-group">
<label for="">标签</label>
<select class="form-control" multiple name="tag">
{% for tag in tag_list %}
{% if tag in tags %}
<option value="{{ tag.id }}" selected>{{ tag.name }}</option>
{% else %}
<option value="{{ tag.id }}">{{ tag.name }}</option>
{% endif %}
{% endfor %}
</select>
</div>
<div class="text-center">
<button class="btn btn-danger">新增文章</button>
</div>
</form>
</div>
{% endblock %}
{% block script %}
<script charset="utf-8" src="/static/kindeditor/kindeditor-all.js"></script>
<script charset="utf-8" src="/static/kindeditor/lang/zh-CN.js"></script>
<script>
KindEditor.ready(function (K) {
window.editor = K.create('#editor_id', {
width: '100%',
height: '600px',
resizeType: 0,
uploadJson: '/upload_file/',
filePostName: 'myfile',
extraFileUploadParams: {
csrfmiddlewaretoken: '{{ csrf_token }}'
}
});
});
</script>
{% endblock %}
后端
# 修改文章
@login_required(login_url='/login/')
def update_article(request):
if request.method == 'GET':
article_id = request.GET.get('id')
article = Article.objects.get(pk=article_id)
article_category = article.category # 当前文章分类
tags = article.tag.all() # 当前文章所有标签
# 拿出当前作者所有分类
category_list = Category.objects.filter(blog=request.user.blog).all()
# 拿出当前作者所有标签
tag_list = Tag.objects.filter(blog=request.user.blog).all()
return render(request, 'backend/update_article.html', locals())
else:
# article_id=request.POST.get('id')
article_id = request.GET.get('id')
title = request.POST.get('title')
content = request.POST.get('content')
category = request.POST.get('category')
tag = request.POST.getlist('tag')
# 处理xss攻击
soup = BeautifulSoup(content) # html标签样子
list_script = soup.find_all('script') # 找到所有script标签,不会包含 用户的代码 已经被特殊字符替换了
for l in list_script:
l.decompose() # 把这个标签从 html中删除
content = str(soup)
desc = soup.text[0:70] # 取摘要,只要文字,不要标签
Article.objects.filter(pk=article_id).update(title=title, content=content, desc=desc, category_id=category)
ArticleToTag.objects.filter(article_id=article_id).delete()
for i in tag:
ArticleToTag.objects.create(article_id=article_id, tag_id=i)
return redirect('/backend/')
修改头像
评论成功发送邮件
# django 发送邮件
- 配置文件修改
EMAIL_HOST = 'smtp.qq.com' # 如果是 163 改成 smtp.163.com
EMAIL_PORT = 465
EMAIL_HOST_USER = '306334678@qq.com' # 帐号
EMAIL_HOST_PASSWORD = '' # 密码
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
#这样收到的邮件,收件人处就会这样显示
#DEFAULT_FROM_EMAIL = 'lqz<'306334678@qq.com>'
EMAIL_USE_SSL = True #使用ssl
#EMAIL_USE_TLS = False # 使用tls
-写代码--同步
from django.core.mail import send_mail
send_mail('您有新评论了,快去看把', '您的文章id:[%s],被[%s],评论了[%s]' % (article_id, request.user.username, content),settings.EMAIL_HOST_USER, ['3418965079@qq.com', '1445545413@qq.com', '306334678@qq.com'])
总结
# 1 富文本编辑器--kindedit
-配置参数
-上传图片---》配合后端接口
-去除xss攻击---》bs4模块
# 2 修改文章
-文章渲染到页面上
# 3 修改头像
-request.user.avatar=文件对象
-save()
# 4 发送邮件
-配置文件
-调用django提供的send_mail---》起线程异步操作
# 5 表 models,表关系
# 6 注册页面
-前端---》form 渲染
-后端-->form校验数据
-头像实时显示
-ajax提交注册
-错误信息渲染 jq 的dom
# 7 登录
-前端
-验证码---》自己写---》借助于第三方--->存在哪
# 8 首页功能---》分页
-文章渲染--for
-轮播图:render,ajax
-页面加载完成,向后端发送请求
-修改密码
-模态框的使用
-alert
# 9 个人站点
-文章显示
-侧边栏:抽取,视图函数合并,路由合并
# 10 文章详情
- 显示文章 |safe
# 11 点赞点踩---》偷样式
类选择器选择标签
前端数字+1
# 12 评论
-render显示根评论和子评论
-ajax提交根评论并显示
-ajax提交子评论并显示
# 13 后台管理
当做作者文章显示
删除文章
# 14 新增文章