Flask基础部分

Flask目录结构(蓝图)

views中存放蓝图,每个蓝图也可以有自己的模板,用蓝图对不同功能的视图函数进行隔离,类似于django中的app

pro_flask包的init.py文件, 用于注册所有的蓝图

from flask import Flask
from pro_flask.views.user import user
from pro_flask.views.blog import blog app = Flask(name, template_folder='templates')

app.register_blueprint(user)

app.register_blueprint(blog)

app.secret_key = "alex"

manage.py文件,作为整个项目的启动文件

from pro_flask import app
from flask_script import Manager
from flask_bootstrap import Bootstrap Bootstrap(app)

manage = Manager(app)

if name == 'main':

# app.call()

manage.run()

views包中的blog.py,必须要通过session验证才能访问,否则回到登录界面

from flask import Blueprint, session, redirect, url_for, render_template

blog = Blueprint("blog", name, template_folder='templates')

@blog.route("/index/")

def index():

return render_template("index.html") @blog.before_request # 请求该蓝图中所有的函数时都会先走这儿!

def process_request():

val = session.get("login")

if val:

return None

else:

return redirect(url_for("user.login")) # 如果没有session则阻断请求

views包中的user.py,定义一些与用户相关的视图函数

from flask import Blueprint, render_template, request, session, url_for, redirect
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, EqualTo, Length, ValidationError user = Blueprint("user", name, template_folder='templates') @user.route("/login/", methods=["GET", "POST"])

def login():

if request.method == "POST":

username = request.form.get("username")

password = request.form.get("password")

if username == "alex" and password == "":

session["name"] = "alex"

session["password"] = ""

session["login"] = 1

return redirect(url_for("blog.index"))

return render_template("login.html") @user.route("/logout/")

def logout():

session.pop("login")

return render_template("base.html") class Register(FlaskForm):
  # username为表单中input中name属性对应的值, "用户名"为label的内容, balidators为验证器(写一些验证表单内容的规则)

username = StringField("用户名", validators=[DataRequired("用户名不能为空"), # 表单的验证器

Length(min=6, max=12, message="长度需要在6~12个字符之间")])

password = PasswordField("密码", validators=[DataRequired("密码不能为空"),

Length(min=6, max=12, message="密码长度需要在6~12个字符之间")])

confirm = PasswordField("确认密码", validators=[DataRequired("密码不能为空"), EqualTo("password", message="两次输入的密码不一致")])

submit = SubmitField("注册")
</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> validate_username(self, field):
</span><span style="color: #0000ff;">if</span> self.username.data == <span style="color: #800000;">"</span><span style="color: #800000;">alex</span><span style="color: #800000;">"</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">raise</span> ValidationError(<span style="color: #800000;">"</span><span style="color: #800000;">该用户已存在</span><span style="color: #800000;">"</span><span style="color: #000000;">)

@user.route("/register/", methods=["GET", "POST"])

def register():

form = Register()

if form.validate_on_submit():

return redirect(url_for("user.login"))

return render_template("register.html", form=form)

加载静态资源的方法

{{ url_for('static',filename='路径/文件名称.css/js/jpg') }}

实例:

{% block metas %}
{{ super() }}
<link rel="icon" href="{{ url_for('static',filename='img/1.jpeg',_external=True) }}">
{% endblock %}

Flask原码部分理解

app.run()方法,负责启动项目,监听请求,那么它在内部做了哪些操作呢???

def run(self):
...
   from werkzeug.serving import run_simple
   run_simple(host, port, self, **options) # 第三个参数self指的是app这个对象自己
   ...

以上是原码中app的run方法的部分内容,其实它执行的是run_simple这个方法

第三个参数将被反射调用,那么app(),就是去执行了app.__call__()方法

可以看出__call__方法其实是在调用wsgi_app这个接口

那么也就是说,将请求相关的所有内容都封装到了一个类的对象中

ctx = self.request_context(environ) # 此时的ctx就是请求的对象

跟进_request_ctx_stack

可以看出将那个请求对象push进了这个LocalStack类的对象里,跟进到LocalStack()中

找到这个push方法,这里的obj就是那个请求的对象

_local是在类初始化时,实例化的Local对象,反射这个Local对象中是否有stack这个属性或方法,如果没有,则执行_local.stack = [], rv = []

在rv列表中把那个请求对象加进来,而_local.stack = [],会触发Local里面的__setattr__方法,所以跟进到Local中查看,Local的实现原理类似于threading.Local


try:
from greenlet import getcurrent as get_ident # 如果有协程库,那么就支持协程
except ImportError:
try:
from thread import get_ident
except ImportError:
from _thread import get_ident # 支持线程
class Local(object):
__slots__ = ('__storage__', '__ident_func__')
</span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__init__</span><span style="color: #000000;">(self):
object.</span><span style="color: #800080;">__setattr__</span>(self, <span style="color: #800000;">'</span><span style="color: #800000;">__storage__</span><span style="color: #800000;">'</span><span style="color: #000000;">, {}) # 使用这种方法不会触发下面的__setattr__方法,避免递归
object.</span><span style="color: #800080;">__setattr__</span>(self, <span style="color: #800000;">'</span><span style="color: #800000;">__ident_func__</span><span style="color: #800000;">'</span><span style="color: #000000;">, get_ident)# 将获取唯一协程标识的方法赋值给了</span>__ident_func__</pre>
   def __getattr__(self, name):
try:
return self.__storage__[self.__ident_func__()][name]
except KeyError:
raise AttributeError(name) def __setattr__(self, name, value):
ident = self.__ident_func__()
storage = self.__storage__
try:
storage[ident][name] = value # 为每个协程/线程开辟空间,如果未开辟 则执行下面的代码
except KeyError:
storage[ident] = {name: value} def __delattr__(self, name):
try:
del self.__storage__[self.__ident_func__()][name]
except KeyError:
raise AttributeError(name)

配置文件的参数

flask中的配置文件是一个flask.config.Config对象(继承字典),默认配置为:

{
'DEBUG': get_debug_flag(default=False), 是否开启Debug模式
'TESTING': False, 是否开启测试模式
'PROPAGATE_EXCEPTIONS': None,
'PRESERVE_CONTEXT_ON_EXCEPTION': None,
'SECRET_KEY': None,
'PERMANENT_SESSION_LIFETIME': timedelta(days=31),
'USE_X_SENDFILE': False,
'LOGGER_NAME': None,
'LOGGER_HANDLER_POLICY': 'always',
'SERVER_NAME': None,
'APPLICATION_ROOT': None,
'SESSION_COOKIE_NAME': 'session',
'SESSION_COOKIE_DOMAIN': None,
'SESSION_COOKIE_PATH': None,
'SESSION_COOKIE_HTTPONLY': True,
'SESSION_COOKIE_SECURE': False,
'SESSION_REFRESH_EACH_REQUEST': True,
'MAX_CONTENT_LENGTH': None,
'SEND_FILE_MAX_AGE_DEFAULT': timedelta(hours=12),
'TRAP_BAD_REQUEST_ERRORS': False,
'TRAP_HTTP_EXCEPTIONS': False,
'EXPLAIN_TEMPLATE_LOADING': False,
'PREFERRED_URL_SCHEME': 'http',
'JSON_AS_ASCII': True,
'JSON_SORT_KEYS': True,
'JSONIFY_PRETTYPRINT_REGULAR': True,
'JSONIFY_MIMETYPE': 'application/json',
'TEMPLATES_AUTO_RELOAD': None,
}

导入配置文件的几种策略

app.config['DEBUG'] = True

PS: 由于Config对象本质上是字典,所以还可以使用app.config.update(...)

app.config.from_pyfile("python文件名称")
如:
settings.py/
DEBUG = True

app.config.from_pyfile("settings.py")

app.config.from_envvar("环境变量名称")

环境变量的值为python文件名称名称,内部调用from_pyfile方法

app.config.from_json("json文件名称")

JSON文件名称,必须是json格式,因为内部会执行json.loads

app.config.from_mapping({'DEBUG':True})

字典格式

app.config.from_object("python类或类的路径")

app.config.from_object('pro_flask.settings.TestingConfig')

settings.py/

class Config(object):

DEBUG = False

TESTING = False

DATABASE_URI = 'sqlite://:memory:' class ProductionConfig(Config):

DATABASE_URI = 'mysql://user@localhost/foo' class DevelopmentConfig(Config):

DEBUG = True class TestingConfig(Config):

TESTING = True PS: 从sys.path中已经存在路径开始写 PS: settings.py文件默认路径要放在程序root_path目录,如果instance_relative_config为True,则就是instance_path目录配置文件

Flask框架整理及配置文件的更多相关文章

  1. Flask框架整理

    Flask基础部分 Flask目录结构(蓝图) views中存放蓝图,每个蓝图也可以有自己的模板,用蓝图对不同功能的视图函数进行隔离,类似于django中的app pro_flask包的init.py ...

  2. Flask框架

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

  3. Flask 框架中 上下文基础理念,包括cookie,session存储方法,requset属性,current_app模块和g模块

    Flask中上下文,分为请求上下文和应用上下文.既状态留存 ,就是把变量存在某一个地方可以调用 请求上下文:实际就是request和session用法理念,既都是可以存储东西. 应用上下文:既变量共享 ...

  4. Flask 框架 重定向,捕获异常,钩子方法及使用jsonify在网页返回json数据

    Flask 框架中常用到重定向方法来实现路由的跳转 ,路由跳转又分为站内跳转和站外跳转 常用的站内跳转方法为url_for  而常用的站外跳转为redirect 在这里提示一下: 在使用两种方法是须调 ...

  5. Flask 框架 debug=Ture 和Json解码:

    Flask框架常用配置文件: 以下推荐四种方法: (一):创建一个配置类. (二):正常代码配置文件. 接下下来两种方法需要新建文件: 步骤为: 1:在当前目录下新建一个文件,名字为:config.i ...

  6. flask框架----信号

    一.实例化补充 instance_path和instance_relative_config是配合来用的.这两个参数是用来找配置文件的,当用app.config.from_pyfile('settin ...

  7. 个人技术博客——linux服务器配置以及flask框架

    本次的软件工程实践,我负责我们组后台服务的搭建,我选用了bandwagon的服务器,安装的是Debian GNU/Linux,全程在root用户下操作,后端服务是用python的flask框架,数据库 ...

  8. flask框架--cookie,session

    今天我又给大家分享一下怎么用flask框架来实现像淘宝购物车一样存储数据,并且把存储的数据删除,这个方法可以用两个方法都可以做成,一个是cookie,另一个是session. session是依赖于c ...

  9. python高级之Flask框架

    目录: Flask基本使用 Flask配置文件 Flask路由系统 Flask模版 Flask请求与响应 Flask之Session Flask之蓝图 Flask之message 中间件 Flask插 ...

随机推荐

  1. python27期前端

    第一天笔记:HTML:是一种标识性的语言css:层叠样式表是一种用来表现HTML等文件样式(效果)的计算机语言JavaScript:简称“JS”,是一种属于网络的脚本语言 常用来为网页添加各式各样的动 ...

  2. LG3119 「USACO2015JAN」Grass Cownoisseur

    问题描述 LG3119 题解 显然,如果有个环,一定是全部走完的. 所以缩点,缩出一个 \(\mathrm{DAG}\) . 只能走一次反向,于是在正图和反图上各跑一次,枚举边,取 \(\mathrm ...

  3. 【day08】PHP

    一. 函数 1.函数:封装的,可以重复使用的完成特定功能的代码段. 2.函数分类:   (1)系统函数   (2)自定义函数 3.自定义函数   (1)格式   function 函数名称([参数[= ...

  4. HTTP协议第一篇:三握手解读

    TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标 ...

  5. 在 React 组件中监听 android 手机物理返回/回退/back键事件

    当前端页面嵌入到 webview 中运行时,有时会需要监听手机的物理返回按键事件来做一些自定义的操作. 比如我最近遇到的,在一个页面里面有批量选择的功能,当点击手机的返回键时,清除页面上的选中状态.我 ...

  6. 解决office365无法登录以及同步的问题

    解决office365无法登录以及同步的问题 You better need to test them one by one. You better need to test them one by ...

  7. java基本类型包装类之间的值比较问题

    废话不多说,先看代码 Integer a = 2;Integer b = 2;if(a==b){ System.out.println("相等");}else{ System.ou ...

  8. POJ 1094 (传递闭包 + 拓扑排序)

    题目链接: POJ 1094 题目大意:有 1 ~ N 个大写字母,且从 A 开始依次 N 个.再给你 M 个小于的关系,比如 A < B ,让你判断三种可能: 1.在第 i 个关系罗列之后,是 ...

  9. javascript判断mp3是否播放完

    javascript判断mp3是否播放完 var audio=document.getElementById('audio'); if(audio){ audio.loop = false; audi ...

  10. HTML+CSS基础 权重的计算 权重计算规则

    权重的计算 将选择器上面的选择器进行叠加,叠加后的总和就是该选择器的权重. 权重计算规则