视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Flask框架的学习指南之制作简单blog系统
2020-11-27 14:17:08 责编:小采
文档
 之前写了一篇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 '' % 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 '' % 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:workdirlog2> set FLASKR_SETTINGS=E:workdirlog2log2setting.py

或者点击我的电脑-->高级-->环境变量,新建一个。

5)创建数据库和表

windows命令行模式下,cd到项目runserver.py那个目录下,进入python shell下:

输入红色部分:

E:workdirlog2>python
Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500  bit (AMD)] 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:

 
 Flaskr
 
 
 

Flaskr

{% if not session.logged_in %} log in {% else %} log out {% endif %} {% for message in get_flashed_messages() %} {{ message }} {% endfor %} {% block body %}{% endblock %}

login.html:

{% extends "layout.html" %}
{% block body %}
 

Login

{% if error %}

Error: {{ error }}{% endif %} {% endblock %}

show_entries.html:

{% extends "layout.html" %}
{% block body %}
 {% if session.logged_in %}
 
 {% endif %}
 
 {% for entry in entries %}
 
  • {{ entry.title }}

    {{ entry.content|safe }} {% else %}
  • Unbelievable. No entries here so far {% endfor %} {% 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文件:

    from blog2.model.User import User
    from blog2.model.Category import Category
    import os
    
    from blog2 import app,db
    from flask import request,render_template,flash,abort,url_for,redirect,session,Flask,g
    
    @app.route('/')
    def show_entries():
    categorys = Category.query.all()
    return render_template('show_entries.html',entries=categorys)
    
    @app.route('/add',methods=['POST'])
    def add_entry():
    if not session.get('logged_in'):
    abort(401)
    title = request.form['title']
    content = request.form['text']
    category = Category(title,content)
    db.session.add(category)
    db.session.commit()
    flash('New entry was successfully posted')
    return redirect(url_for('show_entries'))
    
    @app.route('/login',methods=['GET','POST'])
    def login():
    error = None
    if request.method == 'POST':
    username = request.form['username']
    password = request.form['password']
    user = User.query.filter_by(username=request.form['username']).first()
    passwd = User.query.filter_by(password=request.form['password']).first()
    
    if user is None:
    error = 'Invalid username'
    elif passwd is None:
    error = 'Invalid password'
    else:
    session['logged_in'] = True
    flash('You were logged in')
    return redirect(url_for('show_entries'))
    return render_template('login.html', error=error)
    
    @app.route('/logout')
    def logout():
    session.pop('logged_in', None)
    flash('You were logged out')
    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) 添加条目

    下载本文
    显示全文
    专题