6.1 使用Flask的Demo应用
最短的实现用了34行Python代码和一个22行的Jinja模板。首先,我们有些管理类的任务要做,比如初始化我们的应用并拉近我们的ORM。 1 2 3 4 5 6 7 8 9 10 11 | from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config[ 'SQLALCHEMY_DATABASE_URI' ] = 'sqlite:///test.db'
db = SQLAlchemy(app)
|
现在我们看下我们的模型,这将和另两个样例基本一样。 1 2 3 4 5 | class Lunch(db.Model):
id = db.Column(db.Integer, primary_key = True )
submitter = db.Column(db.String( 63 ))
food = db.Column(db.String( 255 ))
|
哇,相当简单。最难的部分是找到合适的 SQLAlchemy数据类型,选择数据库中String域的长度。使用我们的模型也超级简单,这在于我们将要看到 SQLAlchemy查询语法。
构建我们的提交表单也很简单。在引入Flask-WTForms和正确的域类型后,你可以看到表单看起来有点像我们的模型。主要的区别在于新的提交按钮和食物与提交者姓名域的提示。
应用中的SECRET_KEY域是被WTForms用来创建CSRF符号的。它也被itsdangerous(Flask内包含)用来设置cookies和其他数据。
1 2 3 4 5 6 7 8 9 10 | from flask.ext.wtf import Form
from wtforms.fields import StringField, SubmitField
app.config[ 'SECRET_KEY' ] = 'please, tell nobody'
class LunchForm(Form):
submitter = StringField(u 'Hi, my name is' )
food = StringField(u 'and I ate' )
submit = SubmitField(u 'share my lunch!' )
|
让表单在浏览器中显示意味着模板要有它。我们像下面那样传递进去。 1 2 3 4 5 6 7 | from flask import render_template
@app .route( "/" )
def root():
lunches = Lunch.query. all ()
form = LunchForm()
return render_template( 'index.html' , form = form, lunches = lunches)
|
好了,发生了什么?我们得到已经用Lunch.query.all()提交的午餐列表,并实例化一个表单,让用户提交他们自己的美食之旅。为了简化,变量使用相同的名字出入模板,但这不是必须的。 1 2 3 4 5 6 | < html >
< title >Wut 4 Lunch</ title >
< b >What are people eating?</ b >
< p >Wut4Lunch is the latest social network where you can tell all your friends
about your noontime repast!</ p >
|
这就是模板的真实情况,我们在已经吃过的午餐中循环,并在<ul>中展示他们。这几乎与我们前面看到的循环例子一样。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | < ul >
{% for lunch in lunches %}
< li >< strong >{{ lunch.submitter|safe }}</ strong > just ate < strong >{{ lunch.food|safe }}</ strong >
{% else %}
< li >< em >Nobody has eaten lunch, you must all be starving!</ em ></ li >
{% endfor %}
</ ul >
< b >What are YOU eating?</ b >
< form method = "POST" action = "/new" >
{{ form.hidden_tag() }}
{{ form.submitter.label }} {{ form.submitter(size=40) }}
< br />
{{ form.food.label }} {{ form.food(size=50) }}
< br />
{{ form.submit }}
</ form >
</ html >
|
模板的<form>部分仅仅渲染我们在root()视图中传入模板的WTForm对象的表单标签和输入。当表单提交时,它将向/new提交一个POST请求,这个请求会被下面的函数处理。 1 2 3 4 5 6 7 8 9 10 11 | from flask import url_for, redirect
@app .route(u '/new' , methods = [u 'POST' ])
def newlunch():
form = LunchForm()
if form.validate_on_submit():
lunch = Lunch()
form.populate_obj(lunch)
db.session.add(lunch)
db.session.commit()
return redirect(url_for( 'root' ))
|
在验证了表单数据后,我们把内容放入我们Model对象中,并提交到数据库。一旦我们在数据库中存了午餐,它将在人们吃过的午餐列表中出现。 1 2 3 | if __name__ = = "__main__" :
db.create_all()
app.run()
|
最后,我们只需做(非常)少量的工作来让应用运行起来。使用SQLAlchemy,我们可以创建存储午餐的表,然后开始运行我们写的路径管理就行了。
6.2 测试Django版APP Django版wut4lunch 和Flask版有点像,但是在Django项目中被分到了好几个文件中。首先,我们看看最相似的部分:数据库模型。它和SQLAlchemy版本的唯一不同之处是声明保存文本的数据库字段有轻微的语法区别。
1 2 3 4 5 6 | from django.db import models
class Lunch(models.Model):
submitter = models.CharField(max_length = 63 )
food = models.CharField(max_length = 255 )
|
在表单系统上。不像Flask,我们可以用Django内建的表单系统。它看起来非常像我们在Flask中使用的WTFroms模块,只是语法有点不同。
1 2 3 4 5 6 7 8 9 10 11 12 | from django import forms
from django.http import HttpResponse
from django.shortcuts import render, redirect
from .models import Lunch
class LunchForm(forms.Form):
submitter = forms.CharField(label = 'Your name' )
food = forms.CharField(label = 'What did you eat?' )
|
现在我们只需要构造一个LunchForm实例传递到我们的模板。
1 2 3 4 5 6 7 8 9 10 11 12 | lunch_form = LunchForm(auto_id = False )
def index(request):
lunches = Lunch.objects. all ()
return render(
request,
'wut4lunch/index.html' ,
{
'lunches' : lunches,
'form' : lunch_form,
}
)
|
render函数是Django shortcut,以接受请求、模板路径和一个上下文的dict。与Flask的render_template类似,它也接受接入请求。
1 2 3 4 5 6 | def newlunch(request):
l = Lunch()
l.submitter = request.POST[ 'submitter' ]
l.food = request.POST[ 'food' ]
l.save()
return redirect( 'home' )
|
保存表单应答到数据库是不一样的,Django调用模型的 .save()方法以及处理会话管理而不是用全局数据库会话。干净利落!
Django提供了一些优雅的特性,让我们管理用户提交的午餐,因此我们可以删除那些不合适的午餐信息。Flask和Pyramid没有自动提供这些功能,而在创建一个Django应用时不需要写另一个管理页面当然也是其一个特性。开发者的时间可不免费啊!我们所要做的就是告诉Django-admin我们的模型,是在wut5lunch/admin.py中添加两行。 1 2 | from wut4lunch.models import Lunch
admin.site.register(Lunch)
|
Bam。现在我们可以添加删除一些条目,而无需额外的工作。
|