1.Post类的定义

一个博客文章应该包含最基本的字段:标题、作者、发表时间、摘要、内容、引用(引用可以写进内容里)。从最简单的开始,将字段先写成英文title, author, timestamp, summary, content,当然一个数据库表中肯定需要一个主键id的,在Flask中作为数据库模型类,必须继承db.Model。

1 from . import db
 2 from datetime import datetime
 3 
 4 class Post(db.Model):
 5     __tablename__ = 'posts'
 6     id = db.Column(db.Integer, primary_key=True)
 7     title = db.Column(db.String(64), index=True)
 8     summary = db.Column(db.Text, index=True)
 9     content = db.Column(db.Text)
10     timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
11     author_id = db.Column(db.Integer, db.ForeignKey('users.id'))

Post类定义好后,我们就可以使用Flask-WTF表单模块来进行渲染到前端,这里我们需要定义一个PostForm类,用于前端的数据收集,当数据提交后由视图函数edit-post类将用户提交的数据写入数据库中。

PostForm类:

1 # -*- coding:utf-8 -*-
 2 from flask_wtf import FlaskForm
 3 from wtforms import StringField, SubmitField, TextAreaField
 4 from wtforms.validators import DataRequired, Length
 5 
 6 # 文章类表单
 7 class PostForm(FlaskForm):
 8     title = StringField('文章标题', validators=[DataRequired(), Length(0, 64)])
 9     summary = TextAreaField('摘要', validators=[DataRequired()])
10     content = TextAreaField('留下你的痕迹', validators=[DataRequired()])
11     submit = SubmitField('提交')

接下来就是在视图函数中将表单传入前端模板进行渲染。在这之前需要定义视图函数用于外部用户访问的路由。

edit-post视图函数:

1 # -*- coding:utf-8 -*-
 2 # 导入必要的模块
 3 from flask import render_template,redirect, url_for, flash
 4 from . import main
 5 from ..auth.forms import PostForm
 6 from .. import db
 7 from ..models import Post
 8 from flask_login import current_user, login_required
 9 from ..models import Permission
10 
11 # 写博客的视图函数
12 @main.route('/edit-post', methods=['GET', 'POST'])
13 @login_required
14 def edit_post():
15     if not current_user.is_authenticated:
16         return redirect(url_for('main.index'))
17     form = PostForm()
18     if current_user.can(Permission.WRITE) and form.validate_on_submit():
19         post = Post(title=form.title.data, summary=form.summary.data, content=form.content.data, author=current_user._get_current_object())
20         db.session.add(post)
21         db.session.commit()
22         return redirect(url_for('main.post', id=post.id))
23     return render_template('edit-post.html', form=form)

视图函数编写完成后,接下来就是处理edit-post.html模板了,因为Jinja2支持模板继承,所以edit-post.html通过继承base.html模板来完善布局。这里使用了开源项目editormd,使用markdown语法来编写文章,并且可以及时预览编写的文章效果。

edit-post.html模板:

1 {% extends 'base.html' %}
 2 
 3 {% block title %}云网传输小窝-写文章{% endblock %}
 4 
 5 {% block styles %}
 6 {{ super() }}
 7 <link rel="stylesheet" href="{{ url_for('static',filename='editormd/css/editormd.css') }}"/>
 8 {% endblock styles %}
 9 
10 {% block page_content %}
11 <div class="row">
12     <h1 class="text-center">编辑文章,书写心灵</h1>
13 
14     <form method="POST">
15         {{ form.hidden_tag() }}
16         <div style="float: right; margin-bottom: 5px;">{{ form.submit(class="btn btn-success") }}</div>
17         <div class="form-group">
18             <h4>{{ form.title.label }}</h4>
19             {{ form.title(class="form-control", style="font-size:24px; height:48px") }}
20         </div>
21         <div class="form-group">
22             <h4>{{ form.summary.label }}</h4>        
23             {{ form.summary(style="height:100px; width:100%; resize:none; font-size:20px;", class="form-control") }}
24         </div>
25         <div class="form-group">
26             <h4>{{ form.content.label }}</h4>            
27             <div id="editormd" class="form-control">
28                 {{ form.content(style="display:none;") }}
29             </div>
30         </div>        
31     </form>
32 </div>
33 {% endblock %}
34 
35 {% block scripts %}
36 {{ super() }}
37 <script src="{{ url_for('static',filename='editormd/editormd.min.js') }}"></script>
38 <script type="text/javascript">
39     //初始化编辑器
40     var testEditor;
41     $(function () {
42         testEditor = editormd("editormd", {
43             width: "100%",
44             height: 740,
45             path: '/static/editormd/lib/',
46             theme: "",
47             previewTheme: "",
48             editorTheme: "pastel-on-dark",
49             markdown: "",
50             codeFold: true,
51             saveHTMLToTextarea: true,    // 保存 HTML 到 Textarea
52             searchReplace: true,
53             htmlDecode: "style,script,iframe|on*",            // 开启 HTML 标签解析,为了安全性,默认不开启    
54             emoji: true,
55             taskList: true,
56             tocm: true,         // Using [TOCM]
57             tex: true,                   // 开启科学公式TeX语言支持,默认关闭
58             flowChart: true,             // 开启流程图支持,默认关闭
59             sequenceDiagram: true,       // 开启时序/序列图支持,默认关闭,        
60             imageUpload: true,
61             imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
62             imageUploadURL: "/Center/RichTextUpload",
63             onload: function () {
64                 //干点什么
65             }
66         });
67     });
68     //获取编辑器内容
69     var blogcontent = encodeURIComponent(testEditor.getMarkdown());
70 </script>
71 {{ pagedown.include_pagedown() }}
72 {% endblock scripts %}

最总的页面效果如下所示,嗯...不错哦!

Flask post ImmutableMultiDict 获取 flask post data_html模板

最后我们测试一下,写一个小文章来看看效果。文章提交后,其实我这里只是把md的内容直接保存在数据库了,并没有进行处理,当用户查看文章详情时,会从数据库中读取md数据,前端editormd开源项目会根据md的内容进行渲染,其效果跟写文章的效果是一样的。

Flask post ImmutableMultiDict 获取 flask post data_html_02

2.总结

  • 继续加油!