文章内容

2018/7/12 12:47:52,作 者: 黄兵

Flask Markdown如何处理

在Flask中使用Markdown写文章和评论都不错,但是Markdown具体怎么存储,是应该直接在页面上经过转换显示,还是经过转义成html之后存入数据库?

从页面执行效率上来看我更倾向于后者。

在项目中前者页面加载有一定的延时,而后者直接是从数据库中读出Html之后显示,完全没有页面上的处理延时。

那既然这样,在flask中具体怎么操作呢?

首先看一下模型代码:

# 文章相关表
class Article(db.Model):
    __tablename__ = 'article'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(128))
    body = db.Column(db.Text)
    body_html = db.Column(db.Text)
    create_time = db.Column(db.DateTime, index=True, default=datetime.utcnow)
    seo_link = db.Column(db.String(128))

    @staticmethod
    def on_changed_body(target, value, oldvalue, initiator):
        allowed_tags = ['a', 'abbr', 'acronym', 'b', 'blockquote', 'code',
                        'em', 'i', 'li', 'ol', 'pre', 'strong', 'ul',
                        'h1', 'h2', 'h3', 'p', 'img']
        target.body_html = bleach.linkify(bleach.clean(
            markdown(value, output_format='html'),
            tags=allowed_tags, strip=True))


db.event.listen(Article.body, 'set', Article.on_changed_body)

on_change_body函数注册在body字段上,是SQLAlchemy “set”事件监听程序,这意味着只要这个实例的body字段设置了新值,函数就会被自动调用。on_change_body函数把body字段的文字渲染成HTML格式,结果保存在body_html中,且高效的把Markdown转换成了HTML。

但是在操作中存在各种问题:

1、Markdown中存在图片不显示


至于怎么在前端页面上书写Markdown,可以参考这篇文章:Flask实现Markdown在线编辑与解析

之后存入数据库,在文章页面上显示,一下是HTML的源代码:

<article><p>现在在国内各大网站注册用户名都需要输入电话号码,有些网站比较好,不会给你打骚扰电话,但是有些网站你自从输入了电话号码之后,你的手机就会接到各种各样的推销电话。
<img>
那有什么办法不再受到骚扰,又能注册用户名呢?
在线接收短信平台退出了在线接收短信,详细的操作步骤如下:
1、首先登陆<a href="https://www.pdflibr.com" rel="nofollow">在线接收短信</a>平台,获取电话号码:
<img>
2、注意红框里面就是电话号码,之后我们找到需要注册的页面,输入信息:
<img>
3、点击获取验证码,之后可以看到验证码已经被接收了,我们到<a href="https://www.pdflibr.com" rel="nofollow">在线接收短信</a>平台看看具体短信内容:
<img>
4、之后回到注册页面,输入验证码,点击注册。即可成功注册。
<strong>从此以后再也不怕被骚扰了!</strong></p></article>

可以看到img完全不显示。

需要解决这个问题,参考了一下这篇文章:Flask and Jinja2 with bleach, image HTML not working

修改源代码:

# 文章相关表
class Article(db.Model):
    __tablename__ = 'article'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(128))
    body = db.Column(db.Text)
    body_html = db.Column(db.Text)
    create_time = db.Column(db.DateTime, index=True, default=datetime.utcnow)
    seo_link = db.Column(db.String(128))

    @staticmethod
    def on_changed_body(target, value, oldvalue, initiator):
        allowed_tags = ['a', 'abbr', 'acronym', 'b', 'blockquote', 'code',
                        'em', 'i', 'li', 'ol', 'pre', 'strong', 'ul',
                        'h1', 'h2', 'h3', 'p', 'img', 'video', 'div', 'iframe', 'p', 'br', 'span', 'hr', 'src', 'class']
        allowed_attrs = {'*': ['class'],
                         'a': ['href', 'rel'],
                         'img': ['src', 'alt']}
        target.body_html = bleach.linkify(bleach.clean(
            markdown(value, output_format='html'),
            tags=allowed_tags, strip=True, attributes=allowed_attrs))


db.event.listen(Article.body, 'set', Article.on_changed_body)

其中strip=True是一个剥离标记,具体文章可以参考这里:Stripping markup (strip)


参考资料:

Flask实现Markdown在线编辑与解析

Flask and Jinja2 with bleach, image HTML not working

Stripping markup (strip)¶

开源在线 Markdown 编辑器


黄兵个人博客原创。
转载请注明出处:黄兵个人博客 - Flask Markdown如何处理

分享到:

发表评论

评论列表