Flask框架2
Flask框架的学习与实战(二):实战小项目
昨天写了一篇flask开发环境搭建,今天继续,进行一个实战小项目-blog系统。
blog系统很简单,只有一个页面,然后麻雀虽小五脏俱全。这里目的不是为了做项目而做项目,这篇文章本意是通过这次练习传达以下几个知识点:
1、从全局上了解flask项目的目录结构
2、flask项目的运行机制
3、flask框架实现MVC架构
4、flask-sqlalchemy 操作mysql数据库
一、新建项目:blog系统
在pycharm中,新建flask项目,如下图:
完成后的目录结构是这样的:非常简单,一个static文件夹,一个templates文件夹,一个py文件
以上的目录结构是flask初始时的结构,这个只能应对很小的项目,对于大型复杂的项目,我们需要引入包的管理,MVC架构设计。
二、目录结构重构,引入包管理
针对上面的结构,在最上层blog3目录下,
1、新建一个runserver.py文件,作为项目统一入口文件
2、新建blog文件夹,把已存在的static,templates,blog3.py移到blog文件夹下,然后分别建controller、model文件夹。把blog3.py改名为__init__.py,
现在目录如下所示:
这样就相当于一个大工程结构了:
1)最上层blog2目录是项目名称,一个项目下可以包括多个模块,也就是应用,每个应用下有自己的配置文件,初始化文件,MVC架构。
2)runserver.py:与应用模块平级,作为项目启动文件
3)第二级blog2目录:模块名称
controller目录:MVC中的C,主要存放视图函数
model目录:MVC中的M,主要存放实体类文件,映射数据库中表
templates:MVC中的V,存放html文件
static:静态文件,主要存放css,js等文件
__init__.py:模块初始化文件,Flask 程序对象的创建必须在 __init__.py 文件里完成, 然后我们就可以安全的导入引用每个包。
setting.py:配置文件,数据库用户名密码等等
三、开发代码
1、先把项目运行起来:
1) 编写__init__.py文件,创建项目对象,代码如下:
# -*- coding: utf-8 -*-
from flask import Flask #创建项目对象
app = Flask(__name__)
2) 在runserver.py文件中添加如下代码:

from blog3 import app @app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run(debug=True)

3)运行runserver.py文件:
然后在浏览器中输入:http://127.0.0.1:5000/,会显示helloworld字样
到这里,项目雏形就可以正常运行了,下面的事情就简单了,添加内容,让项目有血有肉吧。
2、设计数据库
本次练习比较简单,就两个表,一个user表,一个文章表。我们采用python的orm框架flask-sqlalchemy实现表的创建、增删改查功能。
在model文件夹中添加User.py和Category.py文件,内容如下:
1) User.py:

from blog2 import db class User(db.Model):
__tablename__ = 'b_user'
id = db.Column(db.Integer,primary_key=True)
username = db.Column(db.String(10),unique=True)
password = db.Column(db.String(16)) def __init__(self,username,password):
self.username = username
self.password = password
def __repr__(self):
return '<User %r>' % self.username

2) Category.py

from blog2 import db class Category(db.Model):
__tablename__ = 'b_category'
id = db.Column(db.Integer,primary_key=True)
title = db.Column(db.String(20),unique=True)
content = db.Column(db.String(100)) def __init__(self,title,content):
self.title = title
self.content = content
def __repr__(self):
return '<Category %r>' % self.title

3)在模块目录blog2下新建setting.py文件,配置数据库连接信息

# _*_ coding: utf-8 _*_ #调试模式是否开启
DEBUG = True SQLALCHEMY_TRACK_MODIFICATIONS = False
#session必须要设置key
SECRET_KEY='A0Zr98j/3yX R~XHH!jmN]LWX/,?RT' #mysql数据库连接信息,这里改为自己的账号
SQLALCHEMY_DATABASE_URI = "mysql://username:password@ip:port/dbname"

4)让项目读取配置文件
修改__init__.py:添加如下内容(红色部分):

# -*- coding: utf-8 -*-
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
#import os
#print os.environ.keys()
#print os.environ.get('FLASKR_SETTINGS')
#加载配置文件内容
app.config.from_object('blog2.setting') #模块下的setting文件名,不用加py后缀
app.config.from_envvar('FLASKR_SETTINGS') #环境变量,指向配置文件setting的路径 #创建数据库对象
db = SQLAlchemy(app)

注意:FLASKR_SETTINGS环境变量需要手工单独设置,window下可以在命令行中输入:
E:\workdir\blog2> set FLASKR_SETTINGS=E:\workdir\blog2\blog2\setting.py
或者点击我的电脑-->高级-->环境变量,新建一个。
5)创建数据库和表
windows命令行模式下,cd到项目runserver.py那个目录下,进入python shell下:
输入红色部分:

E:\workdir\blog2>python
Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on wi
n32
Type "help", "copyright", "credits" or "license" for more information.
>>> from blog2 import db
>>> db.create_all()
>>>
>>>

如果没有任何错误输出代表创建数据库和表成功了。这时我们到数据库中去查看:
数据库已经存在了,再看看表情况:发现没有对应的b_user和b_category表。这是为什么呢?是不是没有找到model目录下的两个类呢。问题在于:__init__.py文件没有引入model包,导致__init__.py无法找到实体类。记住:一切模块对象的创建都在__init__.py中完成
在blog2目录下的__init__.py添加如下代码:
#只有在app对象之后声明,用于导入model否则无法创建表
from blog2.model import User,Category
再次运行上面命令:db.create_all()方法。这时表已经创建成功了。
3、添加界面模板:如登陆页面,显示blog文章页面,添加blog页面
在templates目录下添加三个html文件:
layout.html:

1 <!doctype html>
2 <title>Flaskr</title>
3 <link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
4 <div class=page>
5 <h1>Flaskr</h1>
6 <div class=metanav>
7 {% if not session.logged_in %}
8 <a href="{{ url_for('login') }}">log in</a>
9 {% else %}
10 <a href="{{ url_for('logout') }}">log out</a>
11 {% endif %}
12 </div>
13 {% for message in get_flashed_messages() %}
14 <div class=flash>{{ message }}</div>
15 {% endfor %}
16 {% block body %}{% endblock %}
17 </div>

login.html:

{% extends "layout.html" %}
{% block body %}
<h2>Login</h2>
{% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %}
<form action="{{ url_for('login') }}" method=post>
<dl>
<dt>Username:
<dd><input type=text name=username>
<dt>Password:
<dd><input type=password name=password>
<dd><input type=submit value=Login>
</dl>
</form>
{% endblock %}

show_entries.html:

{% extends "layout.html" %}
{% block body %}
{% if session.logged_in %}
<form action="{{ url_for('add_entry') }}" method='POST' class=add-entry>
<dl>
<dt>Title:
<dd><input type=text size=30 name=title>
<dt>Text:
<dd><textarea name=text rows=5 cols=40></textarea>
<dd><input type=submit value=Share>
</dl>
</form>
{% endif %}
<ul class=entries>
{% for entry in entries %}
<li><h2>{{ entry.title }}</h2>{{ entry.content|safe }}
{% else %}
<li><em>Unbelievable. No entries here so far</em>
{% endfor %}
</ul>
{% endblock %}

对应static中添加css文件:style.css

body { font-family: sans-serif; background: #eee; }
a, h1, h2 { color: #377BA8; }
h1, h2 { font-family: 'Georgia', serif; margin: 0; }
h1 { border-bottom: 2px solid #eee; }
h2 { font-size: 1.2em; } .page { margin: 2em auto; width: 35em; border: 5px solid #ccc;
padding: 0.8em; background: white; }
.entries { list-style: none; margin: 0; padding: 0; }
.entries li { margin: 0.8em 1.2em; }
.entries li h2 { margin-left: -1em; }
.add-entry { font-size: 0.9em; border-bottom: 1px solid #ccc; }
.add-entry dl { font-weight: bold; }
.metanav { text-align: right; font-size: 0.8em; padding: 0.3em;
margin-bottom: 1em; background: #fafafa; }
.flash { background: #CEE5F5; padding: 0.5em;
border: 1px solid #AACBE2; }
.error { background: #F0D6D6; padding: 0.5em; }

4、添加业务逻辑
在controller目录下新建blog_message.py文件:

1 from blog2.model.User import User
2 from blog2.model.Category import Category
3 import os
4
5 from blog2 import app,db
6 from flask import request,render_template,flash,abort,url_for,redirect,session,Flask,g
7
8 @app.route('/')
9 def show_entries():
10 categorys = Category.query.all()
11 return render_template('show_entries.html',entries=categorys)
12
13 @app.route('/add',methods=['POST'])
14 def add_entry():
15 if not session.get('logged_in'):
16 abort(401)
17 title = request.form['title']
18 content = request.form['text']
19 category = Category(title,content)
20 db.session.add(category)
21 db.session.commit()
22 flash('New entry was successfully posted')
23 return redirect(url_for('show_entries'))
24
25 @app.route('/login',methods=['GET','POST'])
26 def login():
27 error = None
28 if request.method == 'POST':
29 username = request.form['username']
30 password = request.form['password']
31 user = User.query.filter_by(username=request.form['username']).first()
32 passwd = User.query.filter_by(password=request.form['password']).first()
33
34 if user is None:
35 error = 'Invalid username'
36 elif passwd is None:
37 error = 'Invalid password'
38 else:
39 session['logged_in'] = True
40 flash('You were logged in')
41 return redirect(url_for('show_entries'))
42 return render_template('login.html', error=error)
43
44
45 @app.route('/logout')
46 def logout():
47 session.pop('logged_in', None)
48 flash('You were logged out')
49 return redirect(url_for('show_entries'))

千万不要忘了在模块级目录下(blog2目录)的__init__.py文件引入视图模块,代码如下:
#只有在app对象之后声明,用于导入view模块
from blog2.controller import blog_manage
5、运行项目,效果如下:
1)输入http://127.0.0.1:5000/,正常情况下你的应该是空白的,因为还没有任何数据。
2)点击log in
忘了告诉你了,你要事先在b_user表中添加一个用户喔,因为登陆要验证用户的,否则你是无法登陆成功的。
3) 添加条目
以上就是这个小项目的所有页面,很简单吧。你一定能搞定!!!
【总结】:通过本次练习,是否对flask框架运行机制有所了解呢,是不是已经有了全局的认识了,如果ok,那么这个小练习就有存在价值了。
参考文献:
【flask快速入门中文版】http://docs.jinkan.org/docs/flask/
【flask快速入门英文版】http://flask.pocoo.org/docs/0.11/
【flask-sqlalchemy中文版】http://www.pythondoc.com/flask-sqlalchemy/index.html
【flask-sqlalchemy英文版】http://flask-sqlalchemy.pocoo.org/2.1/
Flask框架2的更多相关文章
- Flask 框架入门
Flask Flask是一个使用 Python 编写的轻量级 Web 应用框架.其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 . 安装 Flask 依赖两个外部库, We ...
- Flask框架获取用户IP地址的方法
本文实例讲述了python使用Flask框架获取用户IP地址的方法.分享给大家供大家参考.具体如下: 下面的代码包含了html页面和python代码,非常详细,如果你正使用Flask,也可以学习一下最 ...
- Python自动化运维之30、Flask框架
Flask 官网:http://flask.pocoo.org/ flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是 ...
- flask框架+pygal+sqlit3搭建图形化业务数据分析平台
一. 前言 先说下主要的框架和主要的图形库的特点:(个人见解) Django:python开发的一个重量级的web框架,集成了MVC和ORM等技术,设计之初是为了使开发复杂的.数据库驱动的网站变得简单 ...
- 2nd_SE-结对编程1-基于flask框架的四则运算生成器
0x00 Coding https://coding.net/u/nikochan/p/2nd_SE/git 0x01 写在前面 因为在上一个作业中,是基于python完成的Command程序.那么再 ...
- Flask框架
FLask框架的简单介绍 Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请 ...
- Python基于Flask框架配置依赖包信息的项目迁移部署小技巧
一般在本机上完成基于Flask框架的代码编写后,如果有接口或者数据操作方面需求需要把代码部署到指定服务器上. 一般情况下,使用Flask框架开发者大多数都是选择Python虚拟环境来运行项目,不同的虚 ...
- Flask框架(1)--基础
Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后 ...
- Flask框架搭建一个日程表
目录 前言 项目介绍 技术栈 Flask Web开发流程 一.搭建环境 1.1: 创建虚拟环境 1.2: 安装依赖包 1.3: 创建依赖包列表文件 1.4: 测试hello word 二.应用程序开发 ...
- Flask框架搭建REST-API服务
一.目的 为了能够将测试工具部署成RESTful-API服务,这样就能通过接口的方式提供统一测试工具服务,使用人员就不用构建application而产生的各种环境问题.使用问题. 适合人群:Pytho ...
随机推荐
- 嵌入式arm linux环境中gdb+gdbserver调试
一.前言嵌入式Linux系统中,应用开发过程中,很多情况下,用户需要对一个应用程序进行反复调试,特别是复杂的程序.采用GDB方法调试,由于嵌入式系统资源有限性,一般不能直接在目标系统上进行调试,通常采 ...
- VS2012调试C++工程DLL
1.C++工程属性对话框 2.配置属性: (1)常规:输出目录:..\Bin\WFCrawler(调用DLL的工程) 中间目录:..\Bin\WFCrawler(调用DLL的工程 ...
- CSS vertical-align属性的使用方法
这两天写个页面css的时候用到了vertical-align属性.使用过程中踩到了坑,所以总结例如以下: vertical-align的定义 W3C上对vertical-align的定义:vertic ...
- 应用 Valgrind 发现 Linux 程序的内存问题及交叉编译for arm
Valgrind 概述 体系结构 Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合.Valgrind由内核(core)以及基于内核的其他调试工具组成.内核类似于一个框 ...
- Call to a member function assign() on a non-object;thinkphp中报错
这个在自己写的类中 需要function __construct(){parent::__construct();}继承父类构造函数 当发生这个错误的时候,需要在构造函数中集成父类构造
- JavaScript实现form表单的多文件上传
form表单的多文件上传,具体内容如下 formData对象可以使用一系列的键值对来模拟一个完整的表单,然后使用Ajax来发送这个表单 使用<form>表单初始化FormData对象的方式 ...
- 序列 mysql
CREATE TABLE emp_seq (seq INT); INSERT INTO emp_seq VALUES(0); UPDATE emp_seq SET seq = LAST_INSERT_ ...
- html中的span有value属性么(可以作为自定义属性在jquery中用)
html中的span有value属性么(可以作为自定义属性在jquery中用) 一.总结 可以作为自定义属性在jquery中用 二.html中的span有value属性么 value并不是span标签 ...
- 使用pprof及Go 程序的性能优化
使用Golang 程序的性能优化及 Pprof 程序的性能优化无非就是对程序占用资源的优化.对于服务器而言,最重要的两项资源莫过于 CPU 和内存.性能优化,就是在对于不影响程序数据处理能力的情况下, ...
- HDU 5387 Clock(分数类+模拟)
题意: 给你一个格式为hh:mm:ss的时间,问:该时间时针与分针.时针与秒针.分针与秒针之间夹角的度数是多少. 若夹角度数不是整数,则输出最简分数形式A/B,即A与B互质. 解析: 先计算出总的秒数 ...