在flask_admin安装flask_ckeditor富文本编辑器,并配置图片上传
一、功能描述
测试在flask_admin的后台,为一个字段添加ckeditor富文本编辑器,并适当调整后台的显示效果。
相关文档:
- https://flask-admin.readthedocs.io/en/latest/
- https://flask-ckeditor.readthedocs.io/en/latest/index.html
二、测试数据库
class Admin_Table(db.Model):
id = db.Column(db.Integer,primary_key=True)
username = db.Column(db.String(20),unique=True)
password = db.Column(db.String(20))
details = db.Column(db.Text) # 要采用ckeditor编辑的字段
三、准备阶段
-
pip安装flask_ckeditor
-
下载ckeditor4的文件:https://download.cksource.com/CKEditor/CKEditor/CKEditor 4.17.2/ckeditor_4.17.2_full.zip
-
在项目路径中新建static文件夹,放入ckeditor解压之后的文件(这里的路径是static/js/ckeditor)
- 在项目路径新建templates文件夹,新建edit.html文件,代码如下
四、HTML(jinja2)代码
{% extends 'admin/model/edit.html' %}
{% block tail %}
{{ super() }}
<!-- 文档默认使用{{ ckeditor.load }}加载,这里使用的是下载的本地文件来加载 -->
{{ ckeditor.load(custom_url=url_for('static', filename='js/ckeditor/ckeditor.js')) }}
<script>
// 字段detail是要替换的字段
CKEDITOR.replace('details', {
height:500, // 编辑器的高度
filebrowserUploadUrl: '/upload/?', // 图片文件要上传的路径,加?是为了添加粘贴上传的功能
disallowedContent: 'img{width,height};img[width,height]' // 去掉上传图片之后,默认添加的width和height
});
</script>
{% endblock %}
三、python代码
from flask import Flask,url_for,request,send_from_directory
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
from flask_ckeditor import CKEditor,upload_fail,upload_success
from os import path
from PIL import Image
import hashlib
from jinja2.filters import do_striptags
app = Flask("flask_login_admin")
BASEDIR = path.abspath(path.dirname(__file__))
app.secret_key = "mykey"
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///TestDB.sqlite3"
app.config['CKEDITOR_PKG_TYPE'] = 'full' # ckeditor的按钮种类分为basic,standard还有full
app.config['CKEDITOR_FILE_UPLOADER'] = 'upload' # 图片文件要上传路径
app.config['UPLOADED_PATH'] = path.join(BASEDIR,'files') # 图片上传文件夹
ckeditor = CKEditor(app=app)
# 测试数据库模型
db = SQLAlchemy(app=app)
class Admin_Table(db.Model):
id = db.Column(db.Integer,primary_key=True)
username = db.Column(db.String(20),unique=True)
password = db.Column(db.String(20))
details = db.Column(db.Text)
# 上传文件的路径
@app.route('/files/<filename>')
def uploaded_files(filename):
path = app.config['UPLOADED_PATH']
return send_from_directory(path, filename)
# 限制上传图片的宽度为600px,并转成jpg;修改文件名为md5值
def resize_pic(f):
image = Image.open(f)
o_width,o_height = image.size
n_height = int(600*o_height/o_width)
new_image = image.resize((600,n_height)).convert("RGB")
obj_md5 = hashlib.md5()
obj_md5.update(new_image.tobytes())
new_file_name = obj_md5.hexdigest() + ".jpg"
if o_width > 600:
return (new_file_name,new_image,True)
else:
return (new_file_name,new_image,False)
# 上传图片路径
@app.route('/upload', methods=['POST'])
def upload():
f = request.files.get('upload') # 这里只能用upload,ckeditor默认的
extension = f.filename.split('.')[-1].lower()
if extension not in ['jpg', 'gif', 'png', 'jpeg']:
return upload_fail(message='Image only!')
else:
new_file_name,new_image,iscompress = resize_pic(f)
if iscompress:
new_image.save(path.join(app.config["UPLOADED_PATH"],new_file_name),"JPEG",quality=50)
else:
new_image.save(path.join(app.config["UPLOADED_PATH"],new_file_name),"JPEG",quality=100)
url = url_for('uploaded_files',filename=new_file_name)
return upload_success(url=url)
# flask_admin
class MyModelView(ModelView):
# 显示的时候,去掉details的所有tag标记,并限制detail只显示120个字,4个参数是固定的
def _details(view,context,model,name):
return do_striptags(model.details)[:120]
create_template = 'edit.html' # 用新建的edit.html代替默认html模板
edit_template = 'edit.html' # 用新建的edit.html代替默认html模板
column_list = ["id","username","password","details"]
column_filters = ["username","password"]
column_searchable_list = ["username","password"]
page_size = 20
column_labels = {
"username":"用户",
"password":"密码",
"details":"个人简介"
}
column_formatters = {
'details':_details
}
admin = Admin(app=app,name="Admin测试",endpoint="admin",template_mode="bootstrap4")
admin.add_view(MyModelView(Admin_Table,db.session))
if __name__ == '__main__':
db.create_all()
app.run(debug=True)