使用 Flask-CKEditor 编辑器功能,在渲染时只渲染出编辑器窗口,页面内的其他内容都渲染到了编辑器内

各位论坛的前辈们好!因为是第一次在论坛发技术提问帖,如有阐述不到位和不全面的部分还请指出,我争取下次更正~发技术贴的原因是在网上找了好久都找不到相关问题解决方法,考虑到实际具体情况,所以才斗胆提问的,因为还在初级菜鸟阶段,求前辈们轻喷 :confounded:,好的,下面就开始正式的提问了。
(因为我做的是一个主要针对韩国用户介绍我们国家各地区火锅种类的博客,所以在一些内容编辑上面使用了韩文)

  1. 我的需求:想在我的flask博客项目里面添加Flask-CKEditor 编辑器功能,这样可以让用户创建帖子时可以上传图片和链接之类的内容。
  2. 过程:
    1)安装
    我使用了pip工具打开CMD进行了安装操作:
    python -m pip install flask-ckeditor
    2)初始化扩展
    _init_.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
from flask_ckeditor import CKEditor


app = Flask(__name__)
app.config["SECRET_KEY"] = "4ac60774b647c110518817f4bd6bde54"
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///site.db"
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
login_manager = LoginManager(app)
login_manager.login_view = "login"
login_manager.login_message_category = "info"
ckeditor = CKEditor(app)


from flaskhotpot import routes

3). 引入CKEditor资源

我在CKEditor提供的Online Builder构建了一个自定义的资源包,下载解压后放到了项目的static目录下, 并引入资源包内的ckeditor.js文件
create_post.html

{% block head %}
{{ super() }}
<script src="{{ url_for('static', filename='ckeditor/ckeditor.js') }}"></script>
{% endblock head %}

4). 创建CKEditor文本区域
a. 与WTForms/Flask-WTF集成
forms.py

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, BooleanField, TextAreaField
from wtforms.fields.core import SelectField
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
from flaskhotpot.models import User
from flask_ckeditor import CKEditorField

class PostForm(FlaskForm):
    title = StringField("글 제목", validators=[DataRequired()])
    region = SelectField(
        "지역 이름",
        choices=[
            (1, "복쪽"),
            (2, "서쪽"),
            (3, "남쪽"),
            (4, "윈구이지역"),
            (5, "기타지역"),
],
    )
    content = CKEditorField("글 내용", validators=[DataRequired()])
    submit = SubmitField("제출")

b. 渲染表单
create_post.html

{% extends "layout.html" %}
{% block head %}
{{ super() }}
<script src="{{ url_for('static', filename='ckeditor/ckeditor.js') }}"></script>
{% endblock head %}

{% block content %}
    <div class="warpper" style="width: 700px; margin: auto">
        <h1>글 작성</h1>
                <form class="form-container" method="POST" action="">
                        {{ form.hidden_tag() }}  
                        <legend class="border-bottom mb-4">{{ legend }}</legend>
                       
                        {{ form.title.label }}<br>
                        {{ form.title() }}<br><br>
                        {{ form.region.label }}<br>
                        {{ form.region() }}<br><br>
                        {{ form.content.label }}<br>
                        {{ form.content() }}
                        <br>

                        {{ form.submit() }}
                </form>

    </div>
    {{ ckeditor.load() }}
    {{ ckeditor.config(name='content') }}

{% endblock content %}

c. 渲染HTML格式的内容时使用了 |safe 后缀
post.html

{% extends "layout.html" %}
{% block content %}
    <section>
         <div class="container">
            <div class="col-md-12">
                <article class="media content-section">
                    <div class="media-body">
                        <div class="article-metadata">
                            <a class="mr-2" href="#">{{ post.author.username }}</a>
                            <small class="text-muted">{{ post.date_posted.strftime('%Y-%m-%d') }}</small>
                        {% if post.author == current_user %}
                        <div>
                            <a class="btn btn-secondary btn-sm mt-1 mb-1" href="{{ url_for('update_post', post_id=post.id) }}">글 업데이트</a>
                            <button type="button" class="btn btn-danger btn-sm m-1" data-toggle="modal" data-target="#deleteModal">글 삭제</button>
                        </div>
                        {% endif %}
                        </div>
                        <h2 class="article-title">{{ post.title }}</h2>
                        <small><a class="article-title" href='#'>{{ post.region }}</a></small>
                        <p class="article-content">{{ post.content|safe }}</p>
                    </div>
                </article>
            </div>
         </div>
    </section>
  1. 做到这一步我期望的效果本来是title和summit部分也可以显示出来的,但实际的显示效果确实浏览器只显示文本框,title和summit 未显示,而且编辑器文本框内部自动显示了一些表单和template上面编辑的韩文内容 :sob:

  2. 补充一些基本信息
    1) sourcetree

2)我的操作系统是window10,python版本为3.8.5,flask版本为2.0.1
编辑器版本为CKEditor4

麻烦论坛里的前辈们看到帮帮忙,感激不尽 :heart: :heart:

1 Like

请问是否介意提供代码仓库? 内容有点多,不太好看:grinning:

好久没有见到这么认真的提问帖子了……

如果自己引入 CKEditor 包,就不用调用这个方法了。

做到这一步我期望的效果本来是title和summit部分也可以显示出来的,但实际的显示效果确实浏览器只显示文本框,title和summit 未显示,而且编辑器文本框内部自动显示了一些表单和template上面编辑的韩文内容

截个图看一下?

可以的可以的~链接如下:

(因为才刚开始学习所以好多都是不成熟的代码请见谅 :dizzy_face:

好的好的,我把{{ ckeditor.load() }}再试试看,另外浏览器截图显示效果如下:

-从截图中可以看到只有文本框,没有title 和summit :dizzy_face:
-另外如果有时间,你也可以参考我回复上一楼时提供的仓库代码,非常感谢!! :heart:

运行试了下,找到原因了。CKEditor 初始化的时候会寻找编辑器字段的 id(对于你的表单类来说也就是 content),然后把这个 id 的元素初始化为编辑器窗口。但是你的整个页面内容都包裹在了一个 id 为 content 的 div 元素里,和表单类里编辑器字段名称重名,这就导致 CKEditor 把页面上的内容都加载到了编辑器窗口里(先定位到的第一个 id 为 content 的元素就是你的页面 div)。

解决办法是要么更改页面主体 div 的 id,要么更改表单字段的名称

真的太谢谢了!!用了你的方法问题已经解决了。

BTW如果我明年回国内一定买你的新书!不回也想办法国际快递 :smile:

1 Like

哈哈,不客气。明年大概可以买到新版了。

1 Like