python flask项目_python flask实现小项目方法

本文详细介绍了使用Python Flask框架创建项目的步骤,包括环境搭建、数据库连接与ORM映射、数据迁移、模板使用等。通过运行指定脚本创建数据库,使用SQLAlchemy和flask-migrate进行数据库迁移。同时,展示了如何启动开发服务器,以及添加用户注册和登录功能。
摘要由CSDN通过智能技术生成

本文目的是为了完成一个项目用到的flask基本知识,例子会逐渐加深。最好对着源码,一步一步走。

下载源码,运行

pip install-r requirements.txt 建立环境

python db_create.py 创建自己数据库

python db_migrate 迁移数据库

————————————————————————————–

flask 不仅简介小巧,同时运用的时候十分灵活。下面简单介绍一下如何编写一个 flask项目。

涉及调用开发服务器,数据库连接以及 ORM 映射,还有数据库的迁移,模板使用。后期再完善会话,管理后台,缓存等。

一 、安装环境

我们使用 flask web框架,并用 sqlalchemy来做数据库映射,并使用 migrate做数据迁移。

$ pip install flask

$ pip install SQLAlchemy==0.7.9$ pip install flask-sqlalchemy

$ pip install flask-migrate

$ pip install sqlalchemy-migrate

二、建立项目

flask 没有 django 那样原生的 manage管理工具(flask-admin可以实现,日后再说)。因此我们需要手动建立目录。新建一个 myproject目录,在里面建 app tmp两个文件夹,然后在 app文件夹里面建立 static, templates 两个文件夹,用来存储静态文件和模板。最后目录结构如下:

├── app

│ ├── static

│ ├── templates

└── tmp

三、 初始化文件

建立一些文件,在 app文件里建立__init__.py models.py views.py 然后在与app 同目录下建立 config.py 和 run.py 此时的目录结构如下:

(env)admin@admindeMacBook-Air:~/project/python/flask/project$ tree

├── app

│ ├── static

│ ├── templates

│ ├──__init__.py

│ ├── models.py

│ ├── views.py

├── config.py

├── run.py

└── tmp

四 、开始项目1hello wrod

打开 (/app/__init.py) 文件,写入#-*- coding: utf-8 -*-

from flask import Flask #引入 flask

app = Flask(__name__) #实例化一个flask 对象

import views #导入 views 模块#from app import views

注意,我们的 app 文件夹其实是一个python包,from app importviews 这句话也就是从 包app里面导入 views模块,所以写成注释的那句话也没错,其他代码实践喜欢写成后面那种

现在我们来开始写我们的视图,打开 (/app/views.py)#-*- coding: utf-8 -*-

from app importappfrom models importUser, Post, ROLE_USER, ROLE_ADMIN

@app.route(‘/’)defindex():return‘hello world, hello flask’

下一步我们将要启动我们的开发服务器,打开 (/run.py)#-*- coding: utf-8 -*-

from app importappif __name__ == ‘__main__’:

app.debug= True #设置调试模式,生产模式的时候要关掉debug

app.run() #启动服务器

这段代码需要注意第一句 from app import app。也许会有疑问,我们的 app 包里,貌似没有 app.py 这样的模块。其实这是 flask 方式和python的导入方式。from app 指导入 app 包里的 __iniy__.py 所以这句话的含义是导入 __.init__.py 里面的 app实例。

打开shell 运行

$ python run.py

(env)admin@admindeMacBook-Air:~/project/python/flask/project$ python run.py* Running on http://127.0.0.1:5000/

*Restarting with reloader

用浏览器打开 http://127.0.0.1:5000/将会看到一个输入 hello world 的页面2连接数据库

下面开始连接数据库引擎 先要做一个简单的配置 打开 (/config.py)#-*- coding: utf-8 -*-

importos

basedir= os.path.abspath(os.path.dirname(__file__))

SQLALCHEMY_DATABASE_URI= ‘sqlite:///%s’ %os.path.join(basedir, ‘app.db’)

SQLALCHEMY_MIGRATE_REPO=os.path.join(basedir, ‘db_repository’)

CSRF_ENABLED=True

SECRET_KEY= ‘you-will-never-guess’

SQLALCHEMY_DATABASE_URI是the Flask-SQLAlchemy必需的扩展。这是我们的数据库文件的路径。

SQLALCHEMY_MIGRATE_REPO 是用来存储SQLAlchemy-migrate数据库文件的文件夹。

然后打开 (/app/__init__.py)#-*- coding: utf-8 -*-

importosfrom flask importFlaskfrom flask.ext.sqlalchemy importSQLAlchemyfrom config importbasedir

app= Flask(__name__)

app.config.from_object(‘config’)#载入配置文件

db = SQLAlchemy(app) #初始化 db 对象#from app import views, models # 引用视图和模型

importviews, models

打开 (/app/models.py)#-*- coding: utf-8 -*-

from app importdb

ROLE_USER=0

ROLE_ADMIN= 1

classUser(db.Model):

id= db.Column(db.Integer, primary_key=True)

nickname=db.Column(db.String(60), index=True, unique=True)

email= db.Column(db.String(120), index=True, unique=True)

role= db.Column(db.SmallInteger, default=ROLE_USER)def __repr__(self):return ‘’ %self.nickname

我们的模型建立了一个 user类,正好是 数据库里面的 user 表,表有四个字段

现在我们的数据库配置已经好了,可是还没有建立数据库。新建一个文件 (/db_create.py)#-*- coding: utf-8 -*-

from migrate.versioning importapifrom config importSQLALCHEMY_DATABASE_URIfrom config importSQLALCHEMY_MIGRATE_REPOfrom app importdbimportos.path

db.create_all()if notos.path.exists(SQLALCHEMY_MIGRATE_REPO):

api.create(SQLALCHEMY_MIGRATE_REPO,'database repository')

api.version_control(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO)else:

api.version_control(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO, api.version(SQLALCHEMY_MIGRATE_REPO))

这个脚本是完全通用的,所有的应用路径名都是从配置文件读取的。当你用在自己的项目时,你可以把脚本拷贝到你的项目目录下就能正常使用了。

打开shell 运行

$ python db_create.py

运行这条命令之后,你就创建了一个新的app.db文件。这是个支持迁移的空sqlite数据库,同时也会生成一个带有几个文件的db_repository目录,这是SQLAlchemy-migrate存储数据库文件的地方,注意如果数据库已存在它就不会再重新生成了。这将帮助我们在丢失了现有的数据库后,再次自动创建出来。

运行

slqite3 app.db>>>.tables>>>user

或者使用 sqlite 图形化客户端,没有需要安装 (windows 下直接下载安装包即可)

$ sudo apt-get install sqlitebrowser3数据库迁移

每当我们更改了 models 。等价于更改了数据库的表结构,这个时候,需要数据库同步。新建 (/db_migrate.py)#-*- coding: utf-8 -*-

importimpfrom migrate.versioning importapifrom app importdbfrom config importSQLALCHEMY_DATABASE_URIfrom config importSQLALCHEMY_MIGRATE_REPO

migration= SQLALCHEMY_MIGRATE_REPO + '/versions/%03d_migration.py' % (api.db_version(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO) + 1)

tmp_module= imp.new_module('old_model')

old_model=api.create_model(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO)exec old_model in tmp_module.__dict__script=api.make_update_script_for_model(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO, tmp_module.meta, db.metadata)

open(migration,'wt').write(script)

api.upgrade(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO)print 'New migration saved as' +migrationprint 'Current database version:' +str(api.db_version(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO))

这个脚本看起来很复杂,SQLAlchemy-migrate通过对比数据库的结构(从app.db文件读取)和models结构(从app/models.py文件读取)的方式来创建迁移任务,两者之间的差异将作为一个迁移脚本记录在迁移库中,迁移脚本知道如何应用或者撤销一次迁移,所以它可以方便的升级或者降级一个数据库的格式。

开始数据库迁移

$ python db_mirgate.py

New migration saved as db_repository/versions/001_migration.py Current database version: 1相应的,我们继续创建数据库 升级和回退的脚本

(/db_upgrade.py)#-*- coding: utf-8 -*-

from migrate.versioning importapifrom config importSQLALCHEMY_DATABASE_URIfrom config importSQLALCHEMY_MIGRATE_REPO

api.upgrade(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO)print 'Current database version:' +str(api.db_version(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO))

(/db_downgrade.py)#-*- coding: utf-8 -*-

from migrate.versioning importapifrom config importSQLALCHEMY_DATABASE_URIfrom config importSQLALCHEMY_MIGRATE_REPO

v=api.db_version(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO)

api.downgrade(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO, v –1)print 'Current database version:' +str(api.db_version(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO))4操作数据库

接下来,我们定义一个新的modelsclass并做第二次迁移归并

打开(/app/models.py)#-*- coding: utf-8 -*-

from app importdb

ROLE_USER=0

ROLE_ADMIN= 1

classUser(db.Model):

id= db.Column(db.Integer, primary_key=True)

nickname=db.Column(db.String(60), index=True, unique=True)

email= db.Column(db.String(120), index=True, unique=True)

role= db.Column(db.SmallInteger, default=ROLE_USER)

posts= db.relationship(‘Post’, db.backref = ‘author’, db.lazyload =‘dynamic’)def __repr__(self):return ‘’ %self.nicknameclassPost(db.Model):

id= db.Column(db.Integer, primary_key=True)

body= db.Column(db.String(140))

timestamp=db.Column(db.DateTime)

user_id=db.Column(db.Integer, db.ForeignKey(‘user.id’))def __repr__(self):return ‘’ %(self.body)

这里我们进行了两个class 的关联。

$ python db_mirgrate.py

New migration saved as db_repository/versions/002_migration.py Current database version: 2打开 (/app/views.py)#-*- coding: utf-8 -*-

from flask importrender_template, flash, redirect, session, url_for, request, gfrom app importapp, dbfrom models importUser, Post, ROLE_USER, ROLE_ADMIN

@app.route(‘/’)defindex():returnrender_template(‘index.html’)

@app.route(‘/adduser//’)defadduser(nickname, email):

u= User(nickname=nickname, email=email)try:

db.session.add(u)

db.session.commit()return‘add successful’exceptException, e:return‘something go wrong’

@app.route(‘/getuser/’)defgetuser(nickname):

user= User.query.filter_by(nickname=nickname).first()return render_template(‘user.html’, user=user)

@app.errorhandler(404)definternal_error(error):return render_template(‘404.html’), 404@app.errorhandler(500)definternal_error(error):

db.session.rollback()return render_template(‘500.html’), 500这次我们使用了模板, 新建(/app/templates/user.html)

user

user

  • user: {{ user.nickname }}
  • email: {{ user.email }}

最后运行

$ python run.py

用浏览器访问 http://127.0.0.1:5000/adduser/username/useremail

最后还可以用 sqlite 客户端打开查看我们的数据库变换。关于更多的数据库操作方法,请阅读 sqlalchemy文档。

最后我们的代码目录结构如下:

(env)admin@admindeMacBook-Air:~/project/python/flask/project$ tree

.

├── app

│ ├──__init__.py

│ ├── models.py

│ ├── static

│ ├── templates

│ │ ├──404.html

│ │ ├──500.html

│ │ ├── index.html

│ │ └── user.html

│ ├── views.py

├── app.db

├── config.py

├── db_create.py

├── db_downgrade.py

├── db_migrate.py

├── db_repository

│ ├──__init__.py

│ ├── manage.py

│ ├── migrate.cfg

│ ├── README

│ └── versions

│ ├── 001_migration.py

│ ├── 002_migration.py

│ ├──__init__.py

├── db_upgrade.py

├── requirements.txt

├── run.py

├── tmp5表单

接下来,我们将要接触表单方面的内容。flask原生提供的表单处理,也比较简单。当然,有了轮子,我们就直接用好了。需要安装一个

Flask-WTF==0.9.4。

安装完之后,打开 (/app/forms.py)#-*- coding: utf-8 -*-

importrefrom flask_wtf importFormfrom flask_wtf.html5 importEmailFieldfrom wtforms importTextField, PasswordField, BooleanFieldfrom wtforms.validators importDataRequired, ValidationErrorfrom models importUserfrom hashlib importmd5classRegisterFrom(Form):

nickname= TextField(‘nickname’, validators=[DataRequired()])

email= EmailField(’email’, validators=[DataRequired()])

password= PasswordField(‘password’, validators=[DataRequired()])

conform= PasswordField(‘conform’, validators=[DataRequired()])defvalidate_nickname(self, field):

nickname=field.data.strip()if len(nickname) < 3 or len(nickname) > 20:raise ValidationError(‘nickname must be 3letter at least’)elif not re.search(r’^\w+$’, nickname):raise ValidationError(‘User names can contain only alphanumeric characters andunderscores.’)else:#验证是否已经注册

u = User.query.filter_by(nickname=nickname).first()ifu:raiseValidationError(‘The nickname already exists’)defvalidate_email(self, field):

email=field.data.strip()

email= User.query.filter_by(email=email).first()ifemail:raiseValidationError(‘The email already exists’)defvalidate_password(self, field):

password=field.data.strip()if len(password) < 6:raise ValidationError(‘password must be 3letter at least’)defvalidate_conform(self, field):

conform=field.data.strip()if self.data[‘password’] !=conform:raise ValidationError(‘the password andconform are different’)

上述代码定义了一个 RegisterFromclass,正好是一个表单,class的字段映射为表单的域。其中 wtforms 中有 TextField, PasswordField, BooleanField这些表单类型,flask_wtf.html5 中 EmailField 则是 html5 规范的。

表单有 form.validate_on_submit() 方法,这个方法执行之前会验证表单域。验证方法和django类似,都是 validate_field 的方法。其中一个参数 field正好是表单的value值 需要注意验证两次密码是否相同的时候,需要用到 self.data 。这是一个字典,包含了表单域的name和value6用户注册

打开(/app/views.py)添加注册方法。

@app.route(‘/account/signup’, methods=[‘GET’, ‘POST’])defsignup():

form=RegisterFrom()if request.method ==‘POST’:ifform.validate_on_submit():

psdmd5=md5(form.data[‘password’])

password=psdmd5.hexdigest()

u= User(nickname=form.data[‘nickname’], email=form.data[’email’], password=password)try:

db.session.add(u)

db.session.commit()

flash(‘signup successful’)exceptException, e:return‘something goes wrong’returnredirect(url_for(‘signin’))return render_template(‘signup.html’, form=form)

模版 新建 (/app/tempaltes/signup.html){% extends “base.html” %}

{% block content %}

{{ form.hidden_tag() }}

{{ form.nickname.label }} {{ form.nickname(size=20) }}

{{ form.email.label }} {{ form.email(size=20) }}

{{ form.password.label }} {{ form.password(size=20) }}

{{ form.conform.label }} {{ form.conform(size=20) }}

{{ form.errors }}

{% endblock %}

其中,主要是用到 form 对象的一些属性。form.nickname.label 是指表单类定义的名字,form.nickname 会转变成 表单域的 html 代码 即

7用户登录

先添加一个用户登录的表单,打开 (/app/forms.py)classLoginForm(Form):

nickname= TextField(‘nickname’, validators=[DataRequired()])

password= PasswordField(‘password’, validators=[DataRequired()])

remember_me= BooleanField(‘remember_me’, default=False)defvalidate_nickname(self, field):

nickname=field.data.strip()if len(nickname) < 3 or len(nickname) > 20:raise ValidationError(‘nickname must be 3letter at least’)elif not re.search(r’^\w+$’, nickname):raise ValidationError(‘User names can contain only alphanumeric characters andunderscores.’)else:returnnickname

用户登录,最简单的方法就是 验证用户名,如果通过,则添加 session,登出的时候,清除session即可,模版里面可以直接使用 request.session用来判断用户登录状态

打开(/app/views.py) 添加登录登出方法

@app.route(‘/account/signin’, methods=[‘GET’, ‘POST’])defsignin():

form=LoginForm()if request.method ==‘POST’:ifform.validate_on_submit():

nickname=form.data[‘nickname’]

psdmd5=md5(form.data[‘password’])

password=psdmd5.hexdigest()

u= User.query.filter_by(nickname=nickname, password=password).first()ifu:

session[‘signin’]=True

flash(‘signin successful’)returnredirect(url_for(‘index’))else:

flash(u’用户名或者密码错误’)return render_template(‘signin.html’, form=form)

@app.route(‘/account/signout’)defsignout():

session.pop(‘signin’, None)

flash(‘signout successful’)returnredirect(‘index’)

注意,我们使用 flask 的时候,用了中文,就必须是 unicode

除了原生的登录方式,我们还可以用flask-login。安装flask-login

此时需要初始化一个 login_manager 对象,打开 (/app/__init__.py)#-*- coding: utf-8 -*-

importosfrom flask importFlaskfrom flask.ext.sqlalchemy importSQLAlchemyfrom flask.ext.login importLoginManagerfrom config importbasedir

app= Flask(__name__)

app.config.from_object(‘config’)

db= SQLAlchemy(app) #初始化数据库管理对象

login_manager = LoginManager() #初始化登录管理对象

login_manager.init_app(app)

login_manager.login_view= “signin” #登录跳转视图

login_manager.login_message = u”Bonvolu ensaluti por uzi tio paĝo.” #登录跳转视图前的输出消息

#from app import views, models

importviews, models

然后打开 (/app/views.py)

添加下面方法, 注释掉之前的 登入登出方法from flask.ext.login importlogin_user, logout_user, current_user, login_requiredfrom app importapp, db, login_manager

@login_manager.user_loaderdefload_user(userid):returnUser.query.get(userid)

@app.route(‘/account/signin’, methods=[‘GET’, ‘POST’])defsignin():

form=LoginForm()if request.method ==‘POST’:ifform.validate_on_submit():

nickname=form.data[‘nickname’]

psdmd5=md5(form.data[‘password’])

password=psdmd5.hexdigest()

remember_me=form.data[‘remember_me’]

user= User.query.filter_by(nickname=nickname, password=password).first()ifuser:

login_user(user, remember=remember_me)

flash(‘signin successful’)return redirect(request.args.get(“next”) orurl_for(“index”))else:

flash(u’用户名或者密码错误’)return render_template(‘signin.html’, form=form)

@app.route(‘/account/signout’)

@login_requireddefsignout():

logout_user()

flash(‘signout successful’)returnredirect(‘index’)

模版也会响应的改,具体看源码吧。

base.html

{% if title %}

{{title}} – microblog{% else %}microblog{% endif %}

Home{% if current_user.is_authenticated() %}signout{% else %}signin{% endif %}

{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}

{% block content %}{% endblock %}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flask 是一款 Python Web 开发框架,它非常轻量级,灵活易用,适合小型的 Web 应用程序开发。在这里,我们将会介绍如何进行一个 Flask 项目的实战开发。 ## 环境搭建 在开始之前,我们需要先安装 Flask 框架。可以使用 pip 工具来安装,打开命令行工具,输入以下命令即可: ``` pip install flask ``` ## 创建项目 接下来,我们需要创建一个 Flask 项目,可以按照以下步骤进行操作: 1. 创建一个项目文件夹,例如 flask_project。 2. 在项目文件夹中创建一个名为 app.py 的 Python 文件。 3. 在 app.py 文件中导入 Flask 模块,并创建一个 Flask 实例。 ```python from flask import Flask app = Flask(__name__) ``` ## 路由设置 我们需要设置路由,以便我们可以通过访问特定的 URL 来触发特定的代码。我们可以使用 app.route() 装饰器来设置路由。例如: ```python @app.route('/') def index(): return 'Hello, World!' ``` 在这个例子中,我们设置了一个路由根目录 /,当用户访问这个 URL 时,会调用 index 函数,并返回一个字符串 'Hello, World!'。 ## 模板引擎 在 Flask 中,我们可以使用模板引擎来渲染 HTML 页面。最常用的模板引擎是 Jinja2。我们需要在项目中创建一个 templates 文件夹,然后在 app.py 文件中设置 Jinja2 模板引擎。 ```python from flask import Flask, render_template app = Flask(__name__) @app.route('/') def index(): return render_template('index.html') ``` 在这个例子中,我们设置了路由根目录 /,当用户访问这个 URL 时,会调用 index 函数,并渲染一个名为 index.html 的模板文件。 ## 数据库连接 在 Flask 中,我们可以使用多种数据存储方式,包括 MySQL、PostgreSQL、SQLite 等。这里以 SQLite 为例进行说明。我们需要在项目中创建一个名为 database.db 的 SQLite 数据库文件,并使用 SQLite3 模块进行连接。 ```python import sqlite3 conn = sqlite3.connect('database.db') ``` ## 表单处理 在 Web 应用程序中,表单是非常重要的组成部分。Flask 提供了 Flask-WTF 扩展来处理表单。我们需要使用 pip 工具安装 Flask-WTF 扩展。 ``` pip install flask-wtf ``` 然后在 app.py 文件中导入 Flask-WTF 扩展,并创建一个表单类。 ```python from flask_wtf import FlaskForm from wtforms import StringField, SubmitField from wtforms.validators import DataRequired class NameForm(FlaskForm): name = StringField('Name', validators=[DataRequired()]) submit = SubmitField('Submit') ``` 在这个例子中,我们创建了一个名为 NameForm 的表单类,包含一个名为 name 的字符串字段和一个名为 submit 的提交按钮。 ## 部署项目 在开发完成之后,我们需要将项目部署到服务器上。最常用的 Web 服务器是 Apache 和 Nginx。Flask 也提供了一个名为 Werkzeug 的开发 Web 服务器,但它只适用于开发环境。在生产环境中,我们需要使用 Apache 或 Nginx。 ## 总结 这就是一个 Flask 项目的基本开发流程。当然,在实际开发中,还有很多其他的问题需要处理,例如用户验证、数据存储等。希望这篇文章能够帮助你入门 Flask 开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值