详解PythonFlask框架的安装及应用_第1页
详解PythonFlask框架的安装及应用_第2页
详解PythonFlask框架的安装及应用_第3页
详解PythonFlask框架的安装及应用_第4页
详解PythonFlask框架的安装及应用_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第详解PythonFlask框架的安装及应用3)数据库初始化(生成表)

第1节的schema.sql用于建表,那么如何执行其中的建表命令呢?db.py中的init_db就是干这个事情的。

definit_db():

"""Clearexistingdataandcreatenewtables."""

db=get_db()#获取数据库(如果没有则创建)

#读取schema.sql中的SQL命令,并用db.executescript执行SQL命令

withcurrent_app.open_resource("schema.sql")asf:

db.executescript(f.read().decode("utf8"))

4)将init_db注册为flask命令

由于数据库初始化并不需要每次启动数据库时运行(不属于运行时需要执行的函数),我们需要将注册成flask一个指令,只要在命令行中敲flaskinit-db就能够执行init_db,其实现方法如下:

@mand("init-db")

@with_appcontext

definit_db_command():

"""Clearexistingdataandcreatenewtables."""

init_db()

click.echo("Initializedthedatabase.")

definit_app(app):

"""RegisterdatabasefunctionswiththeFlaskapp.Thisiscalledby

theapplicationfactory.

app.teardown_appcontext(close_db)#在返回响应后进行清理时调用该函数

app.cli.add_command(init_db_command)#添加一个可以用flask命令调用的新命令

这样,执行完之后,flask.sqlite文件将会出现在instance文件夹。

3.4蓝图和视图

蓝图是一种组织一组相关视图和其他代码的方法。它们不是直接向应用程序注册视图和其他代码,而是向蓝图注册。然后,当蓝图在factory函数中可用时,它将在应用程序中注册。

该项目中有两个蓝图:auth和blog

bp=Blueprint("auth",__name__,url_prefix="/auth")#inauth.py

bp=Blueprint("blog",__name__)#inblog.py

参数分别是:蓝图的名字,import_name(一般为__name__),url前缀

[1].官方DemoGithub仓库

1)auth视图

这里主要有三个路由:

@bp.route("/register",methods=("GET","POST"))

defregister():

@bp.route("/login",methods=("GET","POST"))

deflogin():

@bp.route("/logout")

deflogout():

2)blog视图

这里主要有四个路由:

@bp.route("/")

defindex():

@bp.route("/create",methods=("GET","POST"))

@login_required

defcreate():

@bp.route("/int:id/update",methods=("GET","POST"))

@login_required

defupdate(id):

@bp.route("/int:id/delete",methods=("POST",))

@login_required

defdelete(id):

3)注册视图中各个功能实现介绍

注册

注册逻辑为:首先从POST中获取username和password,然后调用数据库插入操作:

username=request.form[username]password=request.form[password]db.execute(INSERTINTOuser(username,password)VALUES(,),(username,generate_password_hash(password)),)

登录

登录逻辑为:首先从POST中获取username和password,然后调用数据库查询操作,获取该用户的密码,然后进行密码匹配:

user=db.execute(SELECT*FROMuserWHEREusername=,username,)).fetchone()check_password_hash(user[password],password)

密码匹配后,需要创建session:

iferrorisNone:

#storetheuseridinanewsessionandreturntotheindex

session.clear()

session["user_id"]=user["id"]

returnredirect(url_for("index"))

注销

注销需要清空session:

session.clear()

Session

Session逻辑如下:注册一个方法,让其在任何URL请求之前执行,在其中做Session管理:

@bp.before_app_request

defload_logged_in_user():

user_id=session.get('user_id')

ifuser_idisNone:

g.user=None

else:

g.user=get_db().execute(

'SELECT*FROMuserWHEREid=',(user_id,)

).fetchone()

其他View使用认证

其他View也想使用认证该如何做?在auth.py中实现login_required函数,判断user是否为空,如果为空,则跳转到登录页面:

deflogin_required(view):

@functools.wraps(view)

defwrapped_view(**kwargs):

ifg.userisNone:

returnredirect(url_for('auth.login'))

returnview(**kwargs)

returnwrapped_view

4)博客视图中各个功能实现介绍

展示所有博客

逻辑如下:执行数据库查询操作,获取所有博客,然后加载:

@bp.route("/")

defindex():

"""Showalltheposts,mostrecentfirst."""

db=get_db()

posts=db.execute(

"SELECTp.id,title,body,created,author_id,username"

"FROMpostpJOINuseruONp.author_id=u.id"

"ORDERBYcreatedDESC"

).fetchall()

returnrender_template("blog/index.html",posts=posts)

创建博客

逻辑如下:函数前加上@login_required前缀,这样就能自动判断是否已经登录,否则跳到登录页面;创建博客就是获取标题和内容,然后调用插入命令,进行插入:

@bp.route("/create",methods=("GET","POST"))

@login_required

defcreate():

"""Createanewpostforthecurrentuser."""

ifrequest.method=="POST":

title=request.form["title"]

body=request.form["body"]

error=None

ifnottitle:

error="Titleisrequired."

iferrorisnotNone:

flash(error)

else:

db=get_db()

db.execute(

"INSERTINTOpost(title,body,author_id)VALUES(,,)",

(title,body,g.user["id"]),

mit()

returnredirect(url_for("blog.index"))

returnrender_template("blog/create.html")

更新和删除博客

更新和删除博客,需要传入一个id,然后有一个内部函数用于判断该id是否存在:

defget_post(id,check_author=True):

"""Getapostanditsauthorbyid.

Checksthattheidexistsandoptionallythatthecurrentuseris

theauthor.

:paramid:idofposttoget

:paramcheck_author:requirethecurrentusertobetheauthor

:return:thepostwithauthorinformation

:raise404:ifapostwiththegiveniddoesn'texist

:raise403:ifthecurrentuserisn'ttheauthor

post=(

get_db()

.execute(

"SELECTp.id,title,body,created,author_id,username"

"FROMpostpJOINuseruONp.author_id=u.id"

"WHEREp.id=",

(id,),

.fetchone()

ifpostisNone:

abort(404,f"Postid{id}doesn'texist.")

ifcheck_authorandpost["author_id"]!=g.user["id"]:

abort(403)

returnpost

因此,更新的逻辑如下:

@bp.route("/int:id/update",methods=("GET","POST"))

@login_required

defupdate(id):

"""Updateapostifthecurrentuseristheauthor."""

post=get_post(id)

ifrequest.method=="POST":

title=request.form["title"]

body=request.form["body"]

error=None

ifnottitle:

error="Titleisrequired."

iferrorisnotNone:

flash(error)

else:

db=get_db()

db.execute(

"UPDATEpostSETtitle=,body=WHEREid=",(title,body,id)

mit()

returnredirect(url_for("blog.index"))

returnrender_template("blog/update.html",post=post)

删除的逻辑如下:

@bp.route("/int:id/delete",methods=("POST",))

@login_required

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论