这里是使用python和Flask创建web应用。
安装python
最好安装python3的版本。可以直接在python官方网站上下载。这里就不多介绍了,网上有很多教程。
安装Flask
我们使用pip进行安装
pip install flask --index http://pypi.douban.com/simple --trusted-host pypi.douban.com
也有一些其他的方法。我们可以使用下面代码运行一下看是否安装成功
from flask import Flask # 导入包
app = Flask(__name__) # 创建一个Web应用
@app.route('/') # 定义路由(Views),可以理解为定义页面的URL
def index():
return "这是用Python + Flask 搞出来的。" # 渲染页面
if __name__ == "__main__":
app.run(host='127.0.0.1', port=8080) # 运行,指定监听地址为 127.0.0.1:8080
成功后会出现以下结果
网页上也会出现这个
这就说明成功安装上了。
“Hello, World” Flask应用
1、先创建项目目录,我将这个应用命名为microblog。可以在一个新窗口打开。
2、因为应用程序是存在于包中的。 在Python中,包含__init__.py文件的子目录被视为一个可导入的包。 当你导入一个包时,
init
.py会执行并定义这个包暴露给外界的属性。
所以创建一个名为app的包来存放整个应用,要在microblog目录下。其中会有__init__.py文件
在其下文件__init__.py,输入如下的代码:
from flask import Flask
app = Flask(__name__)
from app import routes
app.run(debug=True)
上面的脚本仅仅是从flask中导入的类Flask,并以此类创建了一个应用程序对象。 传递给Flask类的__name__变量是一个Python预定义的变量,它表示当前调用它的模块的名字。
4、路由是应用程序实现的不同URL。 在Flask中,应用程序路由的处理逻辑被编写为Python函数,称为视图函数。 视图函数被映射到一个或多个路由URL,以便Flask知道当客户端请求给定的URL时执行什么逻辑。
在app目录下建一个routes.py文件。并写下第一个视图函数的代码
from app import app
@app.route('/')
@app.route('/index')
def index():
return "Hello, World!"
5、microblog目录下创建一个命名为microblog.py的Python脚本。 它仅拥有一个导入应用程序实例的行:
from app import app
Flask应用程序实例被称为app,是app包的成员。from app import app语句从app包导入其成员app变量。
创建好后会看到如下目录结构
里面的templates会在下面用到,现在可以先不管。
成功运行后会看到如下结果
模板
原先的视图函数返回简单的字符串,我现在要将其扩展为包含完整HTML页面元素的字符串。我们可以这样写
from flask import Flask
app = Flask(__name__)
from app import app
@app.route('/')
@app.route('/index')
def index():
user = {'username': 'Miguel'}
return '''
<html>
<head>
<title>Home Page - Microblog</title>
</head>
<body>
<h1>Hello, ''' + user['username'] + '''!</h1>
</body>
</html>'''
app.run(debug=True)
在浏览器中看到如下结果
但是这种写法并不太好。因为当这个视图函数中的用户和博客不断变化时,里面的代码将会变得很复杂。应用的视图函数及其关联的URL也会持续增长。所以使用模板就有很大帮助。
模板有助于实现页面展现和业务逻辑之间的分离。 在Flask中,模板被编写为单独的文件,存储在应用程序包内的templates文件夹中。 在确定你在microblog目录后,创建一个存储模板的目录。 把这个文件写在app/templates/index.html中:
在index.html文件中写入
<html>
<head>
<title>{{ title }} - Microblog</title>
</head>
<body>
<h1>Hello, {{ user.username }}!</h1>
</body>
</html>
{
{ … }}包含的内容是动态的,只有在运行时才知道具体表示成什么样子。
网页渲染转移到HTML模板之后,视图函数就能被简化:
routes.py文件写入代码
from flask import render_template
from app import app
@app.route('/')
@app.route('/index')
def index():
user = {'username': 'Miguel'}
return render_template('index.html', title='Home', user=user)
init
.py文件写入代码
from flask import Flask
app = Flask(__name__)
from app import routes
app.run(debug=True)
模板中控制语句
index.html文件中写入
<html>
<head>
{% if title %}
<title>{{title}} - microblog</title>
{% else %}
<title>Welcome to microblog</title>
{% endif %}
</head>
<body>
<h1>Hello, {{user.nickname}}!</h1>
</body>
</html></html>
如果视图函数忘记输入页面标题的参数,不会触发异常反而会出现我们自己提供的标题。
init
.py文件和routes.py文件代码不变。
有标题情况
无标题情况
循环
index.html代码
<html>
<head>
{% if title %}
<title>{{ title }} - Microblog</title>
{% else %}
<title>Welcome to Microblog</title>
{% endif %}
</head>
<body>
<h1>Hi, {{ user.username }}!</h1>
{% for post in posts %}
<div><p>{{ post.author.username }} says: <b>{{ post.body }}</b></p></div>
{% endfor %}
</body>
</html>
init
.py文件代码
from flask import Flask
app = Flask(__name__)
from app import routes
app.run(debug=True)
routes.py文件
from flask import render_template
from app import app
@app.route('/')
@app.route('/index')
def index():
user = {'username': 'Miguel'}
posts = [
{
'author': {'username': 'John'},
'body': 'Beautiful day in Portland!'
},
{
'author': {'username': 'Susan'},
'body': 'The Avengers movie was so cool!'
}
]
return render_template('index.html', title='Home', user=user, posts=posts)
结果
模板的继承
从本质上来讲,就是将所有模板中相同的部分转移到一个基础模板中,然后再从它继承过来。
所以我现在要做的是定义一个名为base.html的基本模板,其中包含一个简单的导航栏,以及我之前实现的标题逻辑。 需要在模板文件app/templates/base.html中编写代码如下:
base.html
<html>
<head>
{% if title %}
<title>{{ title }} - Microblog</title>
{% else %}
<title>Welcome to Microblog</title>
{% endif %}
</head>
<body>
<div>Microblog: <a href="/index">Home</a></div>
<hr>
{% block content %}{% endblock %}
</body>
</html>
在这个模板中,我使用block控制语句来定义派生模板可以插入代码的位置。 block被赋予一个唯一的名称,派生的模板可以在提供其内容时进行引用。
通过从基础模板base.html继承HTML元素,我现在可以简化模板index.html了:
{% extends "base.html" %}
{% block content %}
<h1>Hi, {{ user.username }}!</h1>
{% for post in posts %}
<div><p>{{ post.author.username }} says: <b>{{ post.body }}</b></p></div>
{% endfor %}
{% endblock %}
init
.py文件和routes.py文件代码不变。
查看页面。