flask基础入门(基本功能实现)

  花了两周时间学习了flask最基础的知识,并且实现了几个flask基本的功能。
(下面用这篇文章对几个flask的功能进行总结和梳理,本篇文章重点针对的是功能的实现,所以一些知识点的总结不会在这篇文章中出现,例如:http和静态文件(static file)。)
本文参考网络资料以及李辉老师写的《Flask Wed开发实战》进行整理。

搭建显示页面

  我希望搭建一个显示内容的页面,这里我用显示新闻作为一个例子。基本的思路是:用flask搭建一个新闻显示页面,新闻存储在数据库里,每种新闻属于一种类别(体育,政治,等等),可以根据类别选定新闻。

文件夹的基本结构
app文件中编写视图函数、连接数据库、主函数等的相关函数
forms文件编写显示内容所需要的相关表单。
templates文件夹中存放相关的HTML文件

其实也可以去掉表单这个步骤直接将内容通过视图函数注入到HTML文件中。

连接数据库

  我们首先连接数据库。
我这里用的是MySQL+pymysql的一个组合。
数据库url格式为:
‘mysql+pymysql://username:password@host/databasename’
其他的数据库连接格式可以自行网络上查找

1
2
3
4
5
6
7
8
9
10
11
12
from flask_sqlalchemy import SQLAlchemy

class Config(object): # 定义数据库设置的类
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:root@localhost:3306/demo'
SQLALCHEMY_TRACK_MODIFICATIONS=False

app.config.from_object(Config)
# 应用定义的设置类

db = SQLAlchemy(app)
# 在括号内加入app对象才能在例如Navicat中看到相应的修改
print(db) # 检查数据库连接是否正常

我们将使用Flask-SQLAlchemy来管理数据库。
其实我们也可以使用原生的SQL语言来编写,但是使用ORM魔法来书写的优势也有很多。
最直观的优势就是ORM将SQL中的表、字段、记录都做了相应的映射。

表 ->python类
字段(列)->类属性
记录(行)->类实例
关于ORM和SQL代码的区别这里不会做过多的讲解。

创建表、字段并添加内容

当数据库连接成功后我们就可以进行建表

1
2
3
4
5
class News(db.Model):
id = db.Column(db.Integer, primary_key=True)
# 表的字段由db.Column表示,后面是相应的数据类型和是否为主键
body = db.Column(db.Text)
category = db.Column(db.Text)

注意!所有的模型类都需要继承Flask-SQLAlchemy提供的db.Model基类。

数据库操作

tips:一般添加少量内容可以在navicat中直接添加,但是因为在接下来调用数据库内容的时候一样也需要用到CRUD操作的语句,所以我接下来会使用在Python Shell中的语句进行演示。

1
2
3
4
5
6
7
8
9
10
11
>>> from app import db,News # 在对应的目录下进行导入
>>> news1 = News(id='1', category='chinese_sport', body='中国代表团又添两金')
>>> news2 = News(id='2', category='chinese_sport', body='当地时间31日,东京奥运会第八个比赛日,中国体育代表团在举重、帆船帆板、游泳等项目共赢得2金3银1铜。')
>>> news3 = News(id='3', category='world_sport', body='奥运男足半决赛:西班牙VS日本 巴西VS墨西哥')
>>> news4 = News(id='4', category='world_sport', body='美国男篮大胜捷克 浓眉新季将打更多中锋')
>>> db.session.add(news1) # 这里只是对内容进行了添加并没有提交
>>> db.session.add(news2)
>>> db.session.add(news3)
>>> db.session.add(news4)
>>> db.session.commit()
# 只有对内容commit提交之后才对数据库进行了真正的修改

设计视图函数

1
2
3
4
5
6
7
8
from flask import Flask
from flask import render_template

@app.route('/news', methods=['POST', 'GET']) # 装饰器定义url和HTTP方法
def news_classification(): # 定义视图函数
news = News.query.all() # 在数据库中将数据全部取出
return render_template('show_news.html', news=news)
# 选择渲染的模板文件并将变量传到模板

编写模板文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>show_news</title>
</head>
<body>

<h2>News</h2>
{% for new in news %}
<!-- 使用for循环将新闻全部输出 -->
<div class="new">
<p>{{ new.body }}</p>
<!-- body部分才是新闻的主体部分 -->
</div>
{% endfor %}

</body>
</html>

运行测试

1
app.run(debug=True, host='0.0.0.0')

输入相应的url查看效果
新闻显示

给内容添加“分类”属性

  接下来我会给各个新闻添加“分类”属性(列),然后按类别(下拉框指定)显示对应类别的新闻。我在分类的时候希望分的更加详细一点,比如说我希望包含大类和小类,例如体育新闻可以划分为国内体育新闻和国际体育新闻。

编写表单

1
2
3
4
5
6
7
from flask_wtf import FlaskForm
from wtforms import SubmitField, SelectField
from forms import News_select_form

class News_select_form(FlaskForm):
tags = SelectField(label='选择新闻类型', choices=[('chinese_sport', '国内体育新闻'), ('world_sport', '国际体育新闻'), ('choice3', '选择3')])
submit = SubmitField(label='查看')

编写视图函数

1
2
3
4
5
6
7
8
9
10
11
12
app.secret_key = 'secret string' # 加上密钥

@app.route('/select_news', methods=['POST', 'GET'])
def select_news():
form = News_select_form()
if request.method == 'GET':
return render_template('select_news.html', form=form)
if request.method == 'POST': # 提交表单使用的是 post HTTP方法
if form.validate_on_submit():
data = News.query.filter(News.category==request.form.get('tags')) # 从数据库中选择相对应的新闻类别进行显示
print(data)
return render_template('select_news.html', form=form, data=data, id=id)

注意!不加上密钥会报错

编写模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>select_news</title>
</head>
<body>
<form action="/select_news" method="POST">
{{ form.csrf_token }}
{{ form.tags.label }}
{{ form.tags }}
{{ form.submit }}
</form>
<div>新闻:<br>
{% for datas in data %}
{{ datas.id }}
{{ datas.body }}<br>
{% endfor %}
</div>

</body>
</html>

将表单注入HTML供用户尽行选择

效果如图

在网页端实现增删改

  接下来实现在网页端对数据的增删改。基本的思路也还是用Flask-SQLAlchemy语句对数据库进行操作。因为在设计数据库时给每个新闻都设计了主键,也就是说我们只要知道新闻的主键就可以对新闻进行操作。那显示新闻主键只需要在模板中添加一个显示id就好了。

编写表单

1
2
3
4
5
6
7
8
9
class News_change_form(FlaskForm):
tags = SelectField(label='选择新闻类型', choices=[('chinese_sport', '国内体育新闻'), ('world_sport', '国际体育新闻'), ('choice3', '选择3')])
add_str_field = TextAreaField(label='添加内容') # 多行文本输入框
change_str_field = TextAreaField(label='修改新闻内容')
delete_id_field = StringField(label='序号')
change_id_field = StringField(label='序号')
add_botton = SubmitField(label='添加')
delete_botton = SubmitField(label='删除')
change_botton = SubmitField(label='修改')

编写视图函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from forms import News_change_form

@app.route('/change_news', methods=['POST', 'GET'])
def change_news():
form = News_change_form()
if request.method == 'GET':
return render_template('change_news.html', form=form)
if request.method == 'POST':
if form.validate_on_submit():
if form.add_botton.data: # 读取添加输入框中的内容
news_type = request.form.get('tags')
print(news_type)
add_news_body = form.add_str_field.data
print(add_news_body)
add_note = News(body=add_news_body, category=news_type)
db.session.add(add_note)
db.session.commit()
print('添加新闻成功')
if form.delete_botton.data:
delete_news_id = form.delete_id_field.data
print(delete_news_id)
delete_note = News.query.get(delete_news_id)
print(delete_note)
db.session.delete(delete_note)
db.session.commit()
print('删除新闻成功')
if form.change_botton.data:
change_news_id = form.change_id_field.data
print(change_news_id)
change_news_body = form.change_str_field.data
print(change_news_body)
change_note = News.query.get(change_news_id)
change_note.body = change_news_body
db.session.commit()
print('修改新闻成功')
return render_template('change_news.html', form=form)

编写模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>change_news</title>
</head>
<body>
<form action="/change_news" method="POST">
{{ form.csrf_token }}
<div class="add_news">
<h4>添加新闻(选择相应的新闻类型并输入相应的新闻内容)</h4>
{{ form.tags.label }}
{{ form.tags }}<br>
{{ form.add_str_field.label }}<br>
{{ form.add_str_field }}
{{ form.add_botton }}
</div>
<div class="delete_news">
<h4>删除新闻(输入相应的新闻编号)</h4>
{{ form.delete_id_field.label }}
{{ form.delete_id_field }}
{{ form.delete_botton }}
</div>
<div class="change_news">
<h4>修改新闻(输入希望修改的新闻序号,并填写新闻内容)</h4>
{{ form.change_id_field.label }}<br>
{{ form.change_id_field }}<br>
{{ form.change_str_field.label }}<br>
{{ form.change_str_field }}<br>
{{ form.change_botton }}
</div>
</form>
</body>
</html>

修改新闻页面效果

  单单只是用模板来设计页面是非常简陋的,要想是美化页面还需要设计的更加合理以及用静态文件进行渲染。这只是基础的功能实现。