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 %}
最总的页面效果如下所示,嗯...不错哦!
最后我们测试一下,写一个小文章来看看效果。文章提交后,其实我这里只是把md的内容直接保存在数据库了,并没有进行处理,当用户查看文章详情时,会从数据库中读取md数据,前端editormd开源项目会根据md的内容进行渲染,其效果跟写文章的效果是一样的。
2.总结
- 继续加油!