http://docs.mongodb.org/ecosystem/tutorial/write-a-tumblelog-application-with-flask-mongoengine/
介绍本教程描述了 使用流行的Flask框架联合MongoDB数据库建立一个基本的轻博客应用的过程.
轻博客包含两部分1.一个公开的站点,让人们可以浏览帖子,评论帖子2.一个管理站点,让你可以增加和修改帖子
本教程假定你已经熟悉Flask 并基本了解MongoDB,并且已经安装了MongoDB. 我们使用MongoEngine作为对象文档映射器(ODM)这个组件可以满足Flask和MongoDB之间的交互.
安装用pip和virtualenv来隔离Python环境,安装的python 包跟主系统中的无关.
$ virtualenv myproject或者virtualenv -p /usr/bin/python3.3 venv (--extra-search-dir)比用 pyvenv3靠谱source myproject/bin/activate
准备需要的包Flask是一个微框架,因为它提供非常小的核心功能,高度可扩展.对于 轻博客 项目,本教程包含下面的扩展WTForms, 提供简单的form处理Flask-MongoEngine, 提供在MongoEngine, Flask和WTForms之间的集成Flask-Script 简单使用开发服务器
pip install flaskpip install flask-scriptpip install WTFormspip install mongoenginepip install flask_mongoengine
开始建立博客在工程目录下,创建一个 tmubleblog的目录myproject$ mkdir tumblelog在该目录下添加 如下文件
__init__.pyfrom flask import Flaskapp = Flask(__name__)if __name__ == '__main__': app.run()
manage.py用来载入额外的Flask-script, 它提供欧冠你一个开发服务器和shell
# Set the pathimport os, syssys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))from flask.ext.script import Manager, Serverfrom tumblelog import appmanager = Manager(app)# Turn on debugger by default and reloadermanager.add_command("runserver", Server( use_debugger = True, use_reloader = True, host = '0.0.0.0'))if __name__ == "__main__": manager.run()
在测试服务器里运行这个应用
python manage.py runserver
如果运行正常,你访问 http://localhost:5000 就会看到 404的信息
配置MongoEngine和Flask安装Flask扩展,增加配置文件.
tumblelog/__init__.pyfrom flask import Flaskfrom flask.ext.mongoengine import MongoEngineapp = Flask(__name__)app.config["MONGODB_SETTINGS"] = {'DB': "my_tumble_log"}app.config["SECRET_KEY"] = "KeepThisS3cr3t"db = MongoEngine(app)if __name__ == '__main__': app.run()
定义数据库Schema用Flask写轻博客的第一步,就是定义 ’Models’(在MongdoDB中叫做 documents)在这个应用中,你将定义帖子post和评论comments, 所以,每个Post,都包含一个 Comments编辑 models.py文件
import datetimefrom flask import url_forfrom tumblelog import dbclass Post(db.Document): created_at = db.DateTimeField(default=datetime.datetime.now, required=True) title = db.StringField(max_length=255, required=True) slug = db.StringField(max_length=255, required=True) body = db.StringField(required=True) comments = db.ListField(db.EmbeddedDocumentField('Comment')) def get_absolute_url(self): return url_for('post', kwargs={"slug": self.slug}) def __unicode__(self): return self.title meta = { 'allow_inheritance': True, 'indexes': ['-created_at', 'slug'], 'ordering': ['-created_at'] }class Comment(db.EmbeddedDocument): created_at = db.DateTimeField(default=datetime.datetime.now, required=True) body = db.StringField(verbose_name="Comment", required=True) author = db.StringField(verbose_name="Name", max_length=255, required=True)
MongoEngine的语法是简单 易懂的, 如果你有 Django背景,语法看上去很熟悉.这个例子为Post定义了索引: 一个是cteated_at 日期,我们的前端页面将按照日期排序另外一个是单独的帖子slug
用Shell来添加数据manage.py提供一个shell接口给应用,你可以用它来插入数据到轻博客中.配置urls和views之前,你可以用这个接口来同你的轻博客 交互.启动shell
python manage.py shell
用下面的操作,建立第1个帖子
>>> from tumblelog.models import *>>> post = Post(... title="Hello World!",... slug="hello-world",... body="Welcome to my new shiny Tumble log powered by MongoDB, MongoEngine, and Flask"... )>>> post.save()
添加一些评论
>>> post.comments[]>>> comment = Comment(... author="Joe Bloggs",... body="Great post! I'm looking forward to reading your blog!"... )>>> post.comments.append(comment)>>> post.save()
最后,可以查看这个帖子
>>> post = Post.objects.get()>>> post>>> post.comments[]
添加视图(Views)使用Flask基于类的视图系统,允许你为轻博客产生List和Details视图添加views.py,并建立一个post的蓝图(blueprint)
from flask import Blueprint, request, redirect, render_template, url_forfrom flask.views import MethodViewfrom tumblelog.models import Post, Commentposts = Blueprint('posts', __name__, template_folder='templates')class ListView(MethodView): def get(self): posts = Post.objects.all() return render_template('posts/list.html', posts=posts)class DetailView(MethodView): def get(self, slug): post = Post.objects.get_or_404(slug=slug) return render_template('posts/detail.html', post=post)# Register the urlsposts.add_url_rule('/', view_func=ListView.as_view('list'))posts.add_url_rule('//', view_func=DetailView.as_view('detail'))
现在到应用的init.py
里注册蓝图通过在一个方法里注册蓝图,可避免循环依赖.
def register_blueprints(app): # Prevents circular imports from tumblelog.views import posts app.register_blueprint(posts)register_blueprints(app)
添加模板在tumblelog目录下,添加templates目录和templates/posts目录,用来存储temblelog的模板
mkdir -p templates/posts
建立一个基本的模板,其他所有模板都将从这个模板里继承. templates/base.html
<!DOCTYPE html> My Tumblelog .content {padding-top: 80px;} {%- block topbar -%} My Tumblelog Starring Flask, MongoDB and MongoEngine {%- endblock -%} {% block page_header %}{% endblock %} {% block content %}{% endblock %} {% block js_footer %}{% endblock %}
为博客建立一个landing 页面,它将列出所有的帖子.templates/posts/list.html
{% extends "base.html" %}{% block content %} {% for post in posts %} {{ post.title }} {{ post.body|truncate(100) }} {{ post.created_at.strftime('%H:%M %Y-%m-%d') }} | {% with total=post.comments|length %} {{ total }} comment {%- if total > 1 %}s{%- endif -%} {% endwith %} {% endfor %}{% endblock %}
最后 添加templates/posts/detail.html模板,用来显示单独的帖子
-------
代码写到这里,你运行 python manage.py runserver 就可以看到你的轻博客了.
给博客添加评论接下来,你将给读者添加在帖子后面留下评论的功能.用WTForms就可以创建表单,它会更新处理表单数据的视图,也会更新包含在表单里的模板
在视图里处理评论更新和重构views.py,以便它能处理表单.增加import语句和DetailView类
from flask.ext.mongoengine.wtf import model_form...class DetailView(MethodView): form = model_form(Comment, exclude=['created_at']) def get_context(self, slug): post = Post.objects.get_or_404(slug=slug) form = self.form(request.form) context = { "post": post, "form": form } return context def get(self, slug): context = self.get_context(slug) return render_template('posts/detail.html', **context) def post(self, slug): context = self.get_context(slug) form = context.get('form') if form.validate(): comment = Comment() form.populate_obj(comment) post = context.get('post') post.comments.append(comment) post.save() return redirect(url_for('posts.detail', slug=slug)) return render_template('posts/detail.html', **context)
注意:DetailView扩展自默认的Flask MothodView.
增加站点管理界面当然,你可以总是使用shell来发布帖子.下面我们介绍如果给轻博客添加管理界面.你将增加认证和另外的视图.本教程只集中于 添加和编辑帖子. ”删除”