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,python

Flask框架2的更多相关文章

  1. Flask 框架入门

    Flask Flask是一个使用 Python 编写的轻量级 Web 应用框架.其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 . 安装 Flask 依赖两个外部库, We ...

  2. Flask框架获取用户IP地址的方法

    本文实例讲述了python使用Flask框架获取用户IP地址的方法.分享给大家供大家参考.具体如下: 下面的代码包含了html页面和python代码,非常详细,如果你正使用Flask,也可以学习一下最 ...

  3. Python自动化运维之30、Flask框架

    Flask 官网:http://flask.pocoo.org/ flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是 ...

  4. flask框架+pygal+sqlit3搭建图形化业务数据分析平台

    一. 前言 先说下主要的框架和主要的图形库的特点:(个人见解) Django:python开发的一个重量级的web框架,集成了MVC和ORM等技术,设计之初是为了使开发复杂的.数据库驱动的网站变得简单 ...

  5. 2nd_SE-结对编程1-基于flask框架的四则运算生成器

    0x00 Coding https://coding.net/u/nikochan/p/2nd_SE/git 0x01 写在前面 因为在上一个作业中,是基于python完成的Command程序.那么再 ...

  6. Flask框架

    FLask框架的简单介绍 Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请 ...

  7. Python基于Flask框架配置依赖包信息的项目迁移部署小技巧

    一般在本机上完成基于Flask框架的代码编写后,如果有接口或者数据操作方面需求需要把代码部署到指定服务器上. 一般情况下,使用Flask框架开发者大多数都是选择Python虚拟环境来运行项目,不同的虚 ...

  8. Flask框架(1)--基础

    Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后 ...

  9. Flask框架搭建一个日程表

    目录 前言 项目介绍 技术栈 Flask Web开发流程 一.搭建环境 1.1: 创建虚拟环境 1.2: 安装依赖包 1.3: 创建依赖包列表文件 1.4: 测试hello word 二.应用程序开发 ...

  10. Flask框架搭建REST-API服务

    一.目的 为了能够将测试工具部署成RESTful-API服务,这样就能通过接口的方式提供统一测试工具服务,使用人员就不用构建application而产生的各种环境问题.使用问题. 适合人群:Pytho ...

随机推荐

  1. ibatis 开发中的经验 (三)Struts+Spring+Ibatis 开发环境搭建

             ibatis项目中用到了一些基本配置,须要和spring集成,看了看这些配置大部分同hibernate中是一样的,也比較好理解.仅仅是须要他们的配置中每个类的含义,还有当中的一些细节 ...

  2. html5 在移动端的缩放控制

    viewport 语法介绍: 01 <!-- html document --> 02 <meta name="viewport" 03     content= ...

  3. Html中CSS之去除li前面的小黑点,和ul、LI部分属性方法

    对于很多人用div来做网站时,总会用到,但在显示效果时前面总是会有一个小黑点,这个令很多人头痛,但又找不到要源,其它我们可以用以下方法来清除.1.在CSS中写入代码.找到相关性的CSS,在..li和. ...

  4. 【C++竞赛 F】yyy的三角形

    时间限制:2s 内存限制:32MB 问题描述 yyy对三角形非常感兴趣,他有n个木棍,他正在用这些木棍组成三角形.这时xxx拿了两根木棍过来,xxx希望yyy能给他一根木棍,使得xxx可以组成一个三角 ...

  5. [Angular] Subscribing to the valueChanges Observable

    For example we have built a form: form = this.fb.group({ store: this.fb.group({ branch: '', code: '' ...

  6. 使用JSONP解决跨域问题-代码示例

    前段时间用JSONP解决了跨域问题,现在不用了,把代码思路记下来,今后说不定还用得上. JS代码 //查询公告数据 function recentpost(){ $.getJSON(cmsUrl+&q ...

  7. NSArray NSMutableArray 初始化

    NSArray* Array;//此时数组没有初始化,数组=nil [Array objectAtIndex:2];//不会调用其属性方法,这里不会崩溃 NSMutableArray *Mutable ...

  8. 学习鸟哥的Linux私房菜笔记(15)——文件系统

    一.文件结构 为了能在设备上存储与读取文件,我们需要在分区上创立文件系统 文件系统记录目录与文件我们称之为文件结构 每一个文件系统在Linux里都被解释成由一个根目录为起点的目录结构 Linux将各个 ...

  9. Android核心功能开发SearchView使用的开发(代码共享)

    在Android上.搜索是一个核心的用户功能.用户可以搜索可用的任何数据,的内容是否存储在设备本身或者需要促进网络接入上.Android它提供了一个框架,为用户创造一个一致的搜索的搜索体验,它可以帮你 ...

  10. Error: unrecognized flag -version

    按照网上的教程http://www.ituring.com.cn/article/13473 来确认node.js是否成功安装. 须要在命令行输入:node -version. 但是我在命令行输入:n ...