Flask学习笔记:

GitHub上面的Flask实践项目

https://github.com/SilentCC/FlaskWeb

1.Application and Request Context(上下文)

在Flask 中,一般一个view function(视图函数)会处理一个请求

Flask 中提供request context.保证全局只有一个线程的request,而不会同时出现两个request.





Application and Request Context 一共有四种





current_app (Application context)

g (Application context)

request (Request context)

session (Request context)









2.Request Dispatching(请求发送)

当服务器接受一个请求,Flask通过建立一个URL mapping ,为请求找到相应的视图函数。

Flast 利用 app.route 建立这个Map.





>>> from hello import app

>>> app.url_map

Map([<Rule '/' (HEAD, OPTIONS, GET) -> index>,

     <Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,

     <Rule '/user/<name>' (HEAD, OPTIONS, GET) -> user>])





其中 /static/<filename> route 是Flask中特有的。









3.Request Hooks(请求挂钩)

在接受请求或者处理完请求之后,都要执行一段代码。比如请求发送之前,我们需要连接一下数据库。所以

我们可以写一个连接数据库的通用函数。Flask 中Request hook function 提供了这个功能

有四种hook 函数





before_first_request: 当接受第一个请求之前要执行的代码。

before_request :接受每一个请求之前要执行的代码。

after_request:处理完每一个请求之后要执行的代码,只有请求成功处理之后。

teardown_request:处理完每一个请求之后要执行的代码,请求处理失败之后也可以执行的。





在 request hook function 和view function 之间的数据共享是通过全局的g context来完成的。

例如登录之前,通过before_request请求连接数据库的获取用户的信息 g.username。然后在

view function 中就可以调用g.username





4.Responses(回应)

每个view function 都会返回一个value。可以返回html 页面。

但是http 协议要求我们还需要返回一个状态,比如200 就是成功执行请求,400 就是执行请求发生错误。

for example

   app.route('/')

   def index():

        return '<h1>error request<h1>,400'

view function 可以返回两个,也可以返回三个(value,status,headers)

Flask 也提供了专门一个函数make_response()

@app.route('/')

def index2():

        response=make_response('<h1>This document carries a cookie!</h1>')

        response.set_cookie('answer','42')

        return response

除此之外,还有两种response方式:





redirect(重定向) 实际上一个返回三个的response

from flask import redirect

@app.route('/')

def index():

  return redirect('http://www.example.com')





abort(用于抛出错误)

from flask import abort

@app.route('/user/<id>')

def get_user(id):

    user = load_user(id)

    if not user:

        abort(404)

    return '<h1>Hello, %s</h1>' % user.name









5.Extensions

Command-LineOptions with Flask-Script

Flask 具有可扩展性,可以下载很多插件。

比如Flask-script 这个插件,就是可以让Flask使用命令行在后台。

举个列子:

首先下载Flask_script: $ pip install flask-script

要使用Command-LineOptions这个插件,那么hello.py就要做相应的改变。

然后我们在hello.py中可以这么写:





#!/bin/python





from flask import Flask,make_response

from flask.ext.script import Manager

app = Flask(__name__)





manager = Manager(app)





#...





if __name__ =='__main__':

    manager.run()





这个时候在终端,我们就可以用命令。

$ python hello.py

usage: hello.py [-?] {shell,runserver} ...





positional arguments:

  {shell,runserver}

    shell            Runs a Python shell inside Flask application context.

    runserver        Runs the Flask development server i.e. app.run()

其中shell 命令是启动application 中的context的session 前面提到过。

runserver命令是启动Web server的。

在runserver命令中我们可以查看很多命令,$ python hello.py runserver --help

其中有-h,-t,--host,-p,--post 等等

--host可以设置服务器监听的网络地址。--host 0.0.0.0 所有的地址都可以访问服务器。





6.Jinja2 模板引擎。

首先我们理解Jinja2 模板引擎是个什么东西。其实Jinja 模板引擎就是在html的基础上,在需要交互

数据的地方做一些标注,能实现前后端数据交互。这样就省了很多前端传到后端的代码,实现前后端的MVC

,方便开发。Flask 使用Jinja2模板引擎。





Jinja2 模板引擎之 变量

打印变量用{{ Varibles }}

例如:{{ list[0] }} 打印list数组里的第一个元素。

变量的过滤器,我们可以在变量后面加一个过滤器,对变量进行操作.过滤器和变量用|分隔。

例如:{{ name|capitalize}}  把name这个变量的首字母大写。

下面介绍几个过滤器:

Filter name               Description

safe                      Renders the value without applying escaping

capitalize                Converts the first character of the value to uppercase and the rest to lowercase Converts the value to lowercase characters

lower                     ase Converts the value to lowercase characters

upper                     Converts the value to uppercase characters

title                     Capitalizes each word in the value

trim                      Removes leading and trailing whitespace from the value

striptags                 Removes any HTML tags from the value before rendering





其中safe 过滤器的作用是关闭html转义。还有escapes过滤器是html转义。比如一个字符串 s='<h1>hello world</h1>'

{{s|escapes}} 则是将这个字符串转移成html的内容,从而显示<h1>标签的hello world。

如果{{s|safe}} 那就是打印<h1>hello world<h1>









执行语句 用{% %}

if条件

{% if user %}

    Hello,{{ user }}!

{%  else %}

    Hello,Stranger!

{% endif %}

for循环

<ul>

  {% for comment int comments %}

      <li>{{comment}}</li>

  {% endfor %}

</ul>

宏定义 macro

{% macro render_comment(comment)%}

    <li>{{comment}}</li>

{% endmacro %}





<ul>

        {% for comment in comments %}

            {{ render_comment(comment) }}

        {% endfor %}

</ul>

宏定义 macro 还可以导入文件,例如将上面的

{% macro render_comment(comment)%}

    <li>{{comment}}</li>

{% endmacro %}

放到macros.html里面,再通过导入的方式使用宏定义





{% import 'macros.html' as macros %}

<ul>

{% for comment in comments %}

            {{ macros.render_comment(comment) }}

{% endfor %}

</ul>





如果有多处需要用到重复的代码块,可以统一到一个文件里,通过include

    {% include 'common.html' %}





flask还有一个很重要的用法就是继承性。我们可以写一个模板网页base.html

<html>

<head>

{% block head %}

<title>{% block title %}{% endblock %} - My Application</title> {% endblock %}

    </head>

    <body>

        {% block body %}

        {% endblock %}

</body>

</html>

我们再写一个base2.html来继承base.html

 {% extends "base.html" %}

    {% block title %}Index{% endblock %}

    {% block head %}

{{ super() }}

<style>

</style>

{% endblock %}

{% block body %} <h1>Hello, World!</h1> {% endblock %}





这里extends就是继承的标志,

block标签:被block标记的代码块,是可以被改变的

在子页面中,可以新建一个block,也可以对父页面中的block进行重写

super()则是继承父页面中的block中的已有的代码





7.Bootstrap

Flask中也可以使用boostrap,Flask提供了Flask-Bootstrap 扩展包,用来将

使用bootstrap

$ pip install flask-bootstrap  安装flask-bootstrap

from flask.ext.bootstrap import Bootstrap

 # ...

bootstrap = Bootstrap(app)  初始化flask-bootstrap。





8.链接

网页中有很多需要通过url跳转到其他页面的地方,如果是一个固定的URL,就会很简单,但是如果是一个动态的URL

比如带参数的URL,就会比较麻烦。Flask提供了url_for()函数,来统一管理这些URL

url_for最简单的用法,以hello.py中的视图函数名为参数,则会返回这个视图函数的URL

例如:

视图函数:

@app.route('/user/<name>')

def user(name):

    return render_template('user.html',name=name)





url_for('user', name='john', _external=True)则会返回

http://localhost:5000/user/john.





url_for也可以不用视图函数里的参数,用自己定义的例如:

url_for('index', page=2) 会返回 /?page=2.





url_for也可以引用很多固定文件,比如css文件,javascript文件,图片等等

这些固定文件,一般都放在static文件夹下

 url_for('static', filename='css/styles.css', _external=True)

 会返回 http://localhost:5000/static/css/styles.css.





9.日期和时间

Flask提供了flask-moment,依赖于javascript中的jquery.js和moment.js

提供了对时间和日期处理的各种函数

$ pip install flask-moment  安装flask-moment





初始化moment

from flask.ext.moment import Moment

moment = Moment(app)





在网页中导入moment.js





{% block scripts %}

{{ moment.include_moment() }}

{% endblock %}





10.表格

在Flask中使用表格,Flask提供了flask-wtf

$ pip install flask-wtf  安装flask-wtf

flask-wtf 保护网站的避免受到CSRF攻击,所谓CSRF攻击,就是用户在浏览一个网站的时候,获得该网站的

安全验证,此时在这个网页中点击了另一个恶意网站,恶意网站就可以获得用户的信息,操控用户做一些用户不想做的事情

在hello.py中加入密钥,防止CSRG

pp = Flask(__name__)

app.config['SECRET_KEY'] = 'hard to guess string'





SECRET_KEY是密钥,配置密钥的字符串自己可以设置一个,相当于密码





使用表格的时候,flask是将表格在hello.py作为一个类,然后前端再调取这个form Classes

from flask.ext.wtf import Form

from wtforms import StringField, SubmitField from wtforms.validators import Required

class NameForm(Form):

name = StringField('What is your name?', validators=[Required()])

submit = SubmitField('Submit')





前端界面:

<form method="POST">

{{ form.name.label }} {{ form.name() }}

{{ form.submit() }}

</form>





用flask-wtf和flask-bootstrap获得一个表格

{% extends "base.html" %}

{% import "bootstrap/wtf.html" as wtf %}

{% block title %}Flasky{% endblock %}

{% block page_content %}

<div class="page-header">

<h1>Hello, {% if name %}{{ name }}{% else %}Stranger{% endif %}!</h1>

</div>

{{ wtf.quick_form(form) }}

{% endblock %}





bootstrap/wtf.html 定义了函数,提供用Bootstrap的Flask-WTF





11.session

用法和jsp的session类似

from flask import session





12.flash

如果要在网页中弹出提示框,Flask提供了flash

from flask import flash





flash('error')





相应的在前端界面:

{{ get_flashed_messages() }}显示flash里面的内容

如果有很多条flash需要显示

就可以用for循环

{% for message in get_flashed_messages() %}

{{ get_flashed_messages() }}

{% endfor %}





14.整合python shell





def make_shell_context():

return dict(app=app, db=db, User=User, Role=Role) manager.add_command("shell", Shell(make_context=make_shell_context))





maker_shell_context()函数,注册了程序和数据库,已经实体,然后就可以控制台使用shell命令使用

$ python hello.py shell

    >>> app

    <Flask 'app'>

    >>> db

<SQLAlchemy engine='sqlite:////home/flask/flasky/data.sqlite'> >>> User

<class 'app.User'>





13.数据库





14.Mail

Flask 学习篇二:学习Flask过程中的记录的更多相关文章

  1. java web学习总结(二十八) -------------------JSP中的JavaBean

    一.什么是JavaBean JavaBean是一个遵循特定写法的Java类,它通常具有如下特点: 这个Java类必须具有一个无参的构造函数 属性必须私有化. 私有化的属性必须通过public类型的方法 ...

  2. java web学习总结(二十五) -------------------JSP中的九个内置对象

    一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...

  3. 监听器(Listener)学习(二)在开发中的常见应用

    监听器在JavaWeb开发中用得比较多,下面说一下监听器(Listener)在开发中的常见应用: 统计当前在线人数 自定义Session扫描器 一.统计当前在线人数 在JavaWeb应用开发中,有时候 ...

  4. Node.js学习笔记(二) --- CommonJs和Nodejs 中自定义模块

    一. 什么是 CommonJs? JavaScript 是一个强大面向对象语言,它有很多快速高效的解释器. 然而, JavaScript标准定义的 API 是为了构建基于浏览器的应用程序.并没有制定一 ...

  5. lua源码学习篇二:语法分析

    一步步调试,在lparser.c文件中luaY_parser函数是语法分析的重点函数,词法分析也是在这个过程中调用的.在这个过程中,用到一些数据结构,下面会详细说. Proto *luaY_parse ...

  6. UI5-技术篇-jQuery.ajax执行过程中Token验证及JSON格式传值问题

    最近两天在测试OData服务类方法CREATE_DEEP_ENTITY及GET_EXPANDED_ENTITYSET,刚开始采用ODataModel方式调用没有任何问题,但是ODataModel采用的 ...

  7. ant 安装过程中问题记录

    最近在本机安装ant过程中出现一些问题,在此记录一下. 1.Unable to locate tools.jar. Expected to find it in C:/Program Files/Ja ...

  8. Nutch学习笔记二——抓取过程简析

    在上篇学习笔记中http://www.cnblogs.com/huligong1234/p/3464371.html 主要记录Nutch安装及简单运行的过程. 笔记中 通过配置抓取地址http://b ...

  9. C#线程学习笔记二:线程池中的工作者线程

    本笔记摘抄自:https://www.cnblogs.com/zhili/archive/2012/07/18/ThreadPool.html,记录一下学习过程以备后续查用. 一.线程池基础 首先,创 ...

随机推荐

  1. repo_folder

    -- Create table create table REPO_FOLDER ( UUID ) not null, VALID ) not null, CREATE_TIME ) not null ...

  2. beego + websocket 向页面推送数据

    https://blog.csdn.net/u012210379/article/details/72901387 https://blog.csdn.net/u012210379/article/d ...

  3. MTK 隐藏通知栏

     步骤: 源码/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarVie ...

  4. Nginx Session Sticky

    nginx的粘性session主要通过nginx-sticky-module实现 1 下载 nginx-sticky-module 下载地址:https://code.google.com/p/ngi ...

  5. 自定义tag标签-实现long类型转换成Date类型

    数据库里存储的是bigint型的时间,entity实体中存放的是long类型的标签,现在想输出到jsp页面,由于使用的是jstl标签,而要显示的是可读的时间类型,找来找去有个 fmt:formatDa ...

  6. 服务端测试之接口测试工具——postman

    今天跟大家分享一个非常常见大家也非常熟悉的测试工具——postman. 1.安装postman postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件.打开chrome浏览器, ...

  7. 指定cmd窗口或tomcat运行窗口的名称

    1. 指定cmd窗口运行时名称 1)直接执行命令:title 窗口名称 2)bat文件中直接加上命令:title 窗口名称 例子: title test_ v1 java -jar -Dfile.en ...

  8. redis 列表

    Redis 列表(List) Redis列表是简单的字符串列表,按照插入顺序排序.你可以添加一个元素导列表的头部(左边)或者尾部(右边) 一个列表最多可以包含 232 - 1 个元素 (4294967 ...

  9. [Linux] 如何修改 Linux 主机名

    该方法适用于安装了 Linux 系统的Raspberry Pi & Cubieboard. 在终端执行: sudo vi /etc/hosts 你看到的 hosts 文件应该是这样的: 127 ...

  10. 【Spring源码深度解析学习系列】Bean的加载(六)

    Bean的加载所涉及到的大致步骤: 1)转换对应beanName 为什么需要转换beanName呢?因为传入的参数可能是别名,也可能是FactoryBean,所以需要一系列的解析,这些解析内容包括如下 ...