一、概述

最大的特点:短小精悍、可拓展强的一个Web框架。注意点:上下文管理机制,依赖wsgi:werkzurg 模块

二、前奏学习werkzurg

先来回顾一个知识点:一个类加括号会执行__init__方法,一个对象加括号执行__call__方法

事例1:

from werkzeug.wrappers import Request, Response

@Request.application
def hello(request):
return Response('Hello World!') if __name__ == '__main__':
from werkzeug.serving import run_simple
run_simple('localhost', 4000, hello) #封装了请求和相应的对象

flask就是基于上面一步一步搭建起来的!

三、学习flask

第一个flask:

from flask import Flask

duo=Flask(__name__)

duo.run()   

三行  启动了程序,但是访问url,发现是Not  Found  !!!

什么原因呢?按理说访问url,执行函数,返回结果,我们发现我们访问了,但是没有接收,在django应该怎么写,写个路由写个视图,在这也是一样

from flask import Flask

duo=Flask(__name__)

@duo.route('index')
def index():
return "hello world" duo.run() #这下执行就访问成功

这个duo.run 就是启动socket,这个脚本要以主函数去运行的时候,采取执行duo.run,别人如果导入的时候,run是不应该执行的:

from flask import Flask

duo=Flask(__name__)

@duo.route('index')
def index():
return "hello world" if __name__ == '__main__':
duo.run()

一个flasl实现简单的登录:

from flask import Flask,render_template,request,redirect,session 

duo=Flask(__name__)
duo.secret_key='shuai' #加密方式 @duo.route('/login',methods=['GET','POST']) #默认GET 别的请求还要添加
def login(): if request.method == 'GET':
#return 'Login' #HttpResponse django 返回字符串
return render_template('login.html')
#request.form ----------》#request.POST
#request.args ----------》 #request.GET
user=request.form.get('user')
pwd=request.form.get('pwd')
if user=='duoduo' and pwd =='':
session['user']=user
return redirect('/index')
return render_template('login.html',error='用户名或密码错误') @duo.route('/index')
def index():
user=session.get('user')
if not user:
return redirect('login')
return render_template('index.html') if __name__ == '__main__':
duo.run()

login.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
<h1>用户登入</h1>
<form method="post">
<input type="text" name="user">
<input type="password" name="pwd">
<input type="submit" value="提交">{{error}}
</form> </body>
</html>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
<h1>欢迎使用</h1>
<img src="/static/111.jpg" alt=""> #图片自己找个
</body>
</html>

三、Flask

1、简介

1、配置文件

模块+静态文件         Flask(__name__,...)

2、路由系统     装饰器实现的

@duo.route('/index',methods=['GET'])

3、视图             也有fbv,cbv

4、请求相关      导入就能用,django 而是参数

request.form

request.args

request.method

5、响应

字符串‘’

render

redirect

6、模块渲染

7、session

session['xxx']=123

session.get('xxx')

8、fiash   (闪现)

9、中间件     基本不用  请求前的操作

10、特殊的装饰器

假使一个setting.py:

class Foo:
DEBUG=True
TEST=True

一个脚本duoduo.py

path='setting.Foo'

我们如何在path中将Foo这个类找到?如何获取其中大写的静态字段的值:

import importlib

path='setting.Foo'

p,c=path.rsplit('.',maxsplit=1)

m=importlib.import_module(p)

cls=getattr(m,c)

for key in dir(cls):
if key.isupper():
print(key,getattr(cls,key)) #其实这就是配置文件导入原理

答案

2、详解

1、配置文件

flask的配置文件在哪里呢?这些都是默认的配置文件,

from flask import Flask

duo=Flask(__name__)

print(duo.config)

#<Config {'ENV': 'production', 'DEBUG': False, 'TESTING': False, 'PROPAGATE_EXCEPTIONS': None, 
'PRESERVE_CONTEXT_ON_EXCEPTION': None, 'SECRET_KEY': None, 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(31),
'USE_X_SENDFILE': False, 'SERVER_NAME': None, 'APPLICATION_ROOT': '/', 'SESSION_COOKIE_NAME': 'session',
'SESSION_COOKIE_DOMAIN': None, 'SESSION_COOKIE_PATH': None, 'SESSION_COOKIE_HTTPONLY': True,
'SESSION_COOKIE_SECURE': False, 'SESSION_COOKIE_SAMESITE': None, 'SESSION_REFRESH_EACH_REQUEST': True,
'MAX_CONTENT_LENGTH': None, 'SEND_FILE_MAX_AGE_DEFAULT': datetime.timedelta(0, 43200), 'TRAP_BAD_REQUEST_ERRORS': None,
'TRAP_HTTP_EXCEPTIONS': False, 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', 'JSON_AS_ASCII': True,
'JSON_SORT_KEYS': True, 'JSONIFY_PRETTYPRINT_REGULAR': False, 'JSONIFY_MIMETYPE': 'application/json',
'TEMPLATES_AUTO_RELOAD': None, 'MAX_COOKIE_SIZE': 4093}>

配置文件是可以修改的,那在哪里改?我们这有这样一个语法:

duo.config.from_object('setting.Foo')  #还是上面的setting.py文件

我们来看看.from_object 中的源码:

我们以后的配置文件,可以生成不一样的类,开发环境一个类,线上环境一个类,相同的静态属性一个类,我们根据现实的环境只需改一个类名字就可以了

2、路由系统

@duo.route(url,methods(允许请求的方式),endpoint(值))

-endpoint   ,反向生成URL,如果没有endpoint设定的值,那么默认的这就是函数名

-url_for('endpoint设定的值')

from flask import Flask,url_for

duo=Flask(__name__)

# print(duo.config)
duo.config.from_object('setting.Foo')
# print(duo.config) @duo.route('/index/',methods=['GET','POST']) #endpoint就是django反向生成的name,如果不写endpoint,url_for后面的值就是函数名
def index():
print(url_for('index')) #反向生成url
return "hello world" if __name__ == '__main__':
duo.run()

我们在django中有的时候url会带上对象的nid值,这个在flask中是什么的格式呢?

  • @duo.route('/user/<username>')      字符串
  • @duo.route('/post/<int:post_id>')      整数
  • @duo.route('/post/<float:post_id>')    浮点
  • @duo.route('/post/<path:path>')       路径
  • @duo.route('/login', methods=['GET', 'POST'])

但是默认是不支持正则!   

这就是动态的路由

from flask import Flask,url_for

duo=Flask(__name__)

# print(duo.config)
duo.config.from_object('setting.Foo')
# print(duo.config) @duo.route('/index/<int:nid>',methods=['GET','POST']) #int是用来约束在url的值
def index(nid):
print(nid)
print(url_for('index',nid=1)) #有参数要加参数
return "hello world" if __name__ == '__main__':
duo.run()

3、FBV(CBV后面再介绍)

4、请求相关,响应相关

from flask import Flask,jsonify,make_response

duo=Flask(__name__)
@duo.route('/index/<int:nid>',methods=['GET','POST']) #int是用来约束在url的值
def index(nid):
# 请求相关信息
# request.method
# request.args
# request.form
# request.values
# request.cookies
# request.headers
# request.path
# request.full_path
# request.script_root
# request.url
# request.base_url
# request.url_root
# request.host_url
# request.host
# request.files
# obj = request.files['the_file_name']
# obj.save('/var/www/uploads/' + secure_filename(f.filename)) # 响应相关信息
# return "字符串"
# return render_template('html模板路径',**{})
# return redirect('/index.html')
# return jsonify({'k1':'v1'}) #jsonify帮你序列化
obj=make_response('Index') #把返回给用户的字符串,封装到这个对象
obj.headers['duoduo']=666 #设置响应头
return obj
if __name__ == '__main__':
duo.run()

运行后:

6、模板的渲染

一个登入验证,可以导入before_request,没有返回值就是可以通过,有返回值就无法通过

from flask import Flask,request,before_request,session

duo=Flask(__name__)

@duo.before_request
def xxxxx():
if request.path =='/login': #只有登入视图可以访问
return None
if session.get('user') :
return None return redirect('login') # 上面不通过,返回登入页面

-基本数据类型:可以执行python的语法,如:dict.get() list['xx']

-传入函数

django,自动执行

flask,不自动执行

-全局定义函数

@duo.template_global()

@duo.template_filter()

-模板的继承

{%extends '给谁'%}

{%block content%}

{% endblock%}

-include  直接加页面

-安全方式展示

前端:{{obj|safe}}

后端:Markup('obj')

7、session

session在视图中可以字典来使用,为什么能当作字典,我们来看一下源码:

from flask.sessions import SecureCookieSession

继承了dict,不用多说什么

当请求刚进来时:flask读取cookie中session对应的值:将这个值解密并反序列化成字典,放入内存,以便视图函数使用,

当请求结束时:flask会读取内存中字典的值,在进行序列化+加密,写入到用户的cookie中。(这就是session的机制)

session的配置是可以改的,关于session有以下几点:

 'PERMANENT_SESSION_LIFETIME':           timedelta(days=31),     #生命周期
'SESSION_COOKIE_NAME': 'session' #名称
'SESSION_COOKIE_DOMAIN': None #域名
'SESSION_COOKIE_PATH': None #路径
‘SESSION_COOKIE_HTTPONLY': True #支持HP读取
'SESSION_COOKIE_SECURE': False #安全性
'SESSION_REFRESH_EACH_REQUEST': True #最后一次访问的时间保持

8、flash

在session中存储一会数据,读取时通过pop将数据移除,以此来创造一个效果,只存一次,只能取一次

实例:

from flask import Flask,flash,get_flashed_messages

duo=Flask(__name__)
duo.secret_key='duoduo' #这是一个容易忘记的点
#出现secret_key 的报错就是这个设置 @duo.route('/page1')
def page1():
flash('大娃','boy')
flash('二娃','boy')
flash('蛇精','girl')
return 'session' @duo.route('/page2')
def page2():
print(get_flashed_messages(category_filter=['boy'])) return 'session' if __name__ == '__main__':
duo.run()

访问一下,取一下,我们来看看源码:

9、中间件

那我们先来了解一下flask是怎么运行起来的:

先写一个简单的脚本:

from flask import Flask
duo=Flask(__name__) @duo.route('/index')
def index():
print('index')
return 'Index' if __name__ == '__main__':
duo.run()

首先,先点开源码的duo.run:

run的self就是flask的对象,请求进来第三给参数后面加括号,是不是flask的对象加括号,就是调用,对象调用执行__call__方法:

duo.__call__  #进去看看

当上面的脚本运行,只有请求访问,才执行__call__方法

一个简单的应用

from flask import Flask

duo=Flask(__name__)

@duo.route('/index')
def index():
print('index')
return 'Index' class Middleware(object):
def __init__(self,old):
self.old=old def __call__(self, *args, **kwargs):
print('执行前')
ret=self.old(*args,**kwargs)
print('执行后')
return ret if __name__ == '__main__':
duo.wsgi_app=Middleware(duo.wsgi_app)
duo.run()

10、特殊的装饰器(重点)

before_request   #谁先定义执行

after_request   #从后往上执行

这上面两个原理就是把函数名放到一个列表,然后循环的机制

from flask import Flask

duo=Flask(__name__)

@duo.before_request
def x1():
print('before') @duo.after_request
def x2(reponse): #这里必须要有返回值
print('after')
return reponse @duo.route('/index1')
def index1():
print('index')
return 'Index' @duo.route('/order')
def order():
print('order')
return 'order' if __name__ == '__main__':
duo.run()

这里有一个注意点就是,before_request有返回值的话,要走所有的after_request ,在django1.9以前都只是这个流程,后来改了机制,

我们发现1.10以后,走最外面一个中间件就返回。

before_first_request      #只执行启动起来 首次,后就不再执行,后面详细看源码

template_global    #  渲染 全局定义函数

template_filter     #   不一样的全局定义函数

errorhandler   #定制错误信息

@duo.errorhandler(404)
def not_found(arg):
print(arg)
return '没找到' #定制错误信息的页面比较常用

python3-开发进阶Flask的基础的更多相关文章

  1. python3开发进阶-Web框架的前奏

    我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端. 这样我们就可以自己实现Web框架了. 1.自定义web框架 import socket ...

  2. python3-开发进阶Flask的基础(5)

    内容概要: SQLAlchemy flsak-sqlalchemy flask-script flask-migrate Flask的目录结构 一.SQLAlchemy 1.概述 SQLAlchemy ...

  3. python3开发进阶-Django框架的起飞加速一(ORM)

    阅读目录 ORM介绍 Django中的ORM ORM中的Model ORM的操作 一.ORM介绍 1.ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一 ...

  4. python3开发进阶-Django框架起飞前的准备

    阅读目录 安装 创建项目 运行 文件配置的说明 三个组件 一.安装(安装最新LTS版) Django官网下载页面 根据官方的图版本,我们下载1.11版本的,最好用! 有两种下载方式一种直接cmd里: ...

  5. python3-开发进阶Flask的基础(4)

    今日内容: 上下文管理:LocalProxy对象 上下文管理:  请求上下文: request/session   app上下文:app/g 第三方组件:wtforms       1.使用      ...

  6. python3-开发进阶Flask的基础(3)

    上篇我们大概简单描述了一下上下文管理,这篇来具体来说说, 上下管理的request 上下管理的session 第三方组件:flask-session pymysql操作数据库  数据库连接池 一.前奏 ...

  7. python3-开发进阶Flask的基础(2)

    知识回顾 1.django 和flask区别? 最大的不同就是django请求相关的数据,通过参数一个一个传递过去的,而flask就是先把放在某个地方,然后去取,这个东西叫上下文管理 2.什么是wsg ...

  8. python3开发进阶-Django框架的自带认证功能auth模块和User对象的基本操作

    阅读目录 auth模块 User对象 认证进阶 一.auth模块 from django.contrib import auth django.contrib.auth中提供了许多方法,这里主要介绍其 ...

  9. python3开发进阶-Django框架的Form表单系统和基本操作

    阅读目录 什么是Form组件 常用字段和插件 自定义校验的方式 补充进阶 一.什么是Form组件 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标 ...

随机推荐

  1. div遮罩实现禁用鼠标(click、hover等)事件

    这两天在帮老师做网页,今天想实现在一块区域内禁止鼠标的各种事件,本来是想在框架模板的js文件里去修改,但是改代码的时候有点凌乱...感觉应该自己把问题想复杂了. 所以想了想要是能实现在一个区域内(如: ...

  2. isolation forest进行异常点检测

    一.简介 孤立森林(Isolation Forest)是另外一种高效的异常检测算法,它和随机森林类似,但每次选择划分属性和划分点(值)时都是随机的,而不是根据信息增益或者基尼指数来选择.在建树过程中, ...

  3. 可能是是最全的Springboot基础视频分享,告别无视频可学

    一头扎进SpringBoot视频教程 SpringBoot入门 2017年-张志君老师-SpringBoot(新增) 欢迎关注我的微信公众号:"Java面试通关手册" 回复关键字& ...

  4. ProxySQL 故障

    发现直接连接MGR节点是正常的,可以写入,但通过ProxySQL连接就无法show\select\insert 等 使用sysbench对ProxySQL报以下错误: FATAL: `thread_r ...

  5. MySQL数据库设置为只读及测试【转】

    转自 mysql只读模式的设置方法与实验 - yumushui的专栏 - CSDN博客http://blog.csdn.net/yumushui/article/details/41645469 在M ...

  6. Linux用户密码期限修改

    今天有开发报故,sftp无法登录.检查服务都是正常的,之前3月份也出现过此问题,当时忙没有注意,现在看每3个月出现问题.这才想到是密码过期导致的. 先重置用户密码,发现过期日志为Oct 08, 201 ...

  7. 关于Java代码优化的35条建议

    代码优化,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没用,但是, ...

  8. caffe Python API 之上卷积层(Deconvolution)

    对于convolution: output = (input + 2 * p  - k)  / s + 1; 对于deconvolution: output = (input - 1) * s + k ...

  9. 使用keytool生成ssl密钥文件keystore和truststore

    最近在研究Mina的开发,通信的时候需要数据加密,而且mina本身支持SSLFilter过滤器,所以可以采用SSL加密的方式对数据进行加密. 在进行加密之前,我们需要使用keytool(这个存在于C: ...

  10. LeetCode765. Couples Holding Hands

    N couples sit in 2N seats arranged in a row and want to hold hands. We want to know the minimum numb ...