1【虚拟环境】为什么需要虚拟环境

2【虚拟环境】virtualenv创建虚拟环境

3【虚拟环境】virtualenvwrapper使用

4【Flask预热】课程介绍

5【Flask预热】Flask课程准备工作

6【Flask预热】URL组成部分详解

URL 是 Uniform Resource Locator 的简写,统一资源定位符。
一个 URL 由以下几部分组成:

 scheme://host:port/path/?query-string=xxx#anchor
  • scheme:代表的是访问的协议,一般为 http 或者 https 以及 ftp 等。

  • host:主机名,域名,比如 www.baidu.com 。

  • port:端口号。当你访问一个网站的时候,浏览器默认使用80端口。

  • path:查找路径。比如: www.jianshu.com/trending/now ,后面的 trending/now 就 是 path

  • query-string:查询字符串,比如: www.baidu.com/s?wd=python ,后面的 wd=python 就是查
    询字符串。

  • anchor:锚点,后台一般不用管,前端用来做页面定位的。

注意: URL 中的所有字符都是 ASCII 字符集,如果出现非 ASCII 字符,比如中文,浏览器会进行编码再进行传输。


Content-type和Mime-type的作用和区别:

两者都是指定服务器和客户端之间传输数据的类型,区别如下:
Content-type:既可以指定传输数据的类型,也可以指定数据的编码类型,例如: text/html;charset=utf-8
Mime-type:不能指定传输的数据编码类型。例如: text/html
常用的数据类型如下:

Flask视图和URL_flask

7【Flask预热】web服务器+应用服务器+web应用框架

  • web服务器:负责处理http请求,响应静态文件,常见的有 Apache , Nginx 以及微软 的 IIS .
  • 应用服务器:负责处理逻辑的服务器。比如 php 、 python 的代码,是不能直接通 过 nginx这种web服务器来处理的,只能通过应用服务器来处理,常见的应用服务器 有 uwsgi 、 tomcat 等。
  • web应用框架:一般使用某种语言,封装了常用的 web 功能的框架就是web应用框 架, flask 、 Django 以及Java中的SSH(Structs2+Spring3+Hibernate3) 框架都是web应用框架

Flask视图和URL_斜杠_02

8【Flask URL】第一个flask程序详解

Flask简介:

flask 是一款非常流行的 Python Web 框架,出生于2010年,作者是 Armin Ronacher ,本来这个项目只是作者在愚人节的一个玩笑,后来由于非常受欢迎,进而成为一个正式的项目。

flask 自2010年发布第一个版本以来,大受欢迎,深得开发者的喜爱,并且在多个公司已经得到
了应用,flask能如此流行的原因,可以分为以下几点:

  • 微框架、简洁、只做他需要做的,给开发者提供了很大的扩展性。
  • Flask和相应的插件写得很好,用起来很爽。
  • 开发效率非常高,比如使用 SQLAlchemy 的 ORM 操作数据库可以节省开发者大量书写 sql 的时间。

Flask 的灵活度非常之高,他不会帮你做太多的决策,一些你都可以按照自己的意愿进行更改。
比如:

  • 使用 Flask 开发数据库的时候,具体是使用 SQLAlchemy 还是 MongoEngine ,选择权完全掌握在你自己的手中。区别于 Django , Django 内置了非常完善和丰富的功能,并且如果你想替换成你自己想要的,要么不支持,要么非常麻烦。

  • 把默认的 Jinija2 模板引擎替换成其他模板引擎都是非常容易的。

#coding: utf8    

# 从flask框架中导入Flask类
from flask import Flask

# 传入__name__初始化一个Flask实例
app = Flask(__name__)

# app.route装饰器映射URL和执行的函数。这个设置将根URL映射到了hello_world函数上
@app.route('/')
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    # 运行本项目,host=0.0.0.0可以让其他电脑也能访问到该网站,port指定访问的端口。默认的host是127.0.0.1,port为5000
    app.run(host='127.0.0.1',port=9000)

详细介绍:


# 从flask这个包中导入Flask这个类
# Flask这个类是项目的核心,以后很多操作都是基于这个类的对象
# 注册url、注册蓝图等都是基于这个类的对象
from flask import Flask

# 创建一个Flask对象,传递__name__参数进去
# __name__参数的作用:
# 1. 可以规定模版和静态文件的查找路径
# 2. 以后一些Flask插件,比如Flask-migrate、Flask-SQLAlchemy如果报错了,那么Flask
# 可以通过这个参数找到具体的错误位置
app = Flask(__name__)

# @app.route:是一个装饰器
# @app.route('/')就是将url中的/映射到hello_world这个视图函数上面
# 以后你访问我这个网站的/目录的时候,会执行hello_world这个函数,然后将这个函数的返回值
# 返回给浏览器。
# wwww.baidu.com/ -> hello_world函数
@app.route('/')
def hello_world():
    return 'major'

# www.baidu.com/list/
@app.route('/list/')
def my_list():
    return 'my list'


# 如果这个文件是作为一个主文件运行,那么就执行app.run()方法
# 也就是启动这个网站
if __name__ == '__main__':
    # app.run():Flask中的一个测试应用服务器
    # while True:
    #   listen()
    #   input()
    app.run(port=8000)

9【Flask URL】debug模式详解

默认情况下flask不会开启DEBUG模式,开启DEBUG模式后,flask会在每次保存代码的时候自动的重新载入代码,并且如果代码有错误,会在终端进行提示。

开启DEBUG模式有三种方式:

1.直接在应用对象上设置:

app.debug = True
app.run()

2.在执行run方法的时候,传递参数进去:

app.run(debug=True)

3.在config属性中设置:
config是个字典型

app.config.update(DEBUG=True)

如果一切正常,会在终端打印以下信息:

* Restarting with stat
* Debugger is active!
* Debugger pin code: 294-745-044
* Running on http://0.0.0.0:9000/ (Press CTRL+C to quit)

需要注意的是,只能在开发环境下开启DEBUG模式,因为DEBUG模式会带来非常大的安全隐患。

另外,在开启了DEBUG模式后,当程序有异常而进入错误堆栈模式,你第一次点击某个堆栈想查看变量值的时候,页面会弹出一个对话框,让你输入PIN值,这个PIN值在你启动的时候就会出现。

比如在刚刚启动的项目中的PIN值为294-745-044,你输入这个值后,Werkzeug会把这个PIN值作为cookie的一部分保存起来,并在8小时候过期,8小时以内不需要再输入PIN值。

这样做的目的是为了更加的安全,让调试模式下的攻击者更难攻击到本站。

实例

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello():
    a = 1
    b = 0
    c = a/b
    return "major"


if __name__ == '__main__':
    app.run(debug=True)

Flask视图和URL_flask_03
Flask视图和URL_flask_04
补充:

config.py
DEBUG必须大写

DEBUG=True

app.py

import config

app.config.from_object(config)

10【Flask URL】配置文件两种方式详解

Flask项目的配置,都是通过app.config对象来进行配置的。比如要配置一个项目处于DEBUG模式下,那么可以使用app.config['DEBUG] = True来进行设置,那么Flask项目将以DEBUG模式运行。在Flask项目中,有四种方式进行项目的配置:

1.直接硬编码:

app = Flask(__name__)
app.config['DEBUG'] = True

2.因为app.config是flask.config.Config的实例,而Config类是继承自dict,因此可以通过update方法:

app.config.update(
   DEBUG=True,
   SECRET_KEY='...'
)

3.如果你的配置项特别多,你可以把所有的配置项都放在一个模块中,然后通过加载模块的方式进行配置,假设有一个settings.py模块,专门用来存储配置项的,此时你可以通过app.config.from_object()方法进行加载,并且该方法既可以接收模块的的字符串名称,也可以模块对象:




# 1. 通过模块字符串
app.config.from_object('settings')





# 2. 通过模块对象
import settings
app.config.from_object(settings)

4.也可以通过另外一个方法加载,该方法就是app.config.from_pyfile(),该方法传入一个文件名,通常是以.py结尾的文件,但也不限于只使用.py后缀的文件

app.config.from_pyfile('settings.py',silent=True)
# silent=True表示如果配置文件不存在的时候不抛出异常,默认是为False,会抛出异常。

Flask项目内置了许多的配置项,所有的内置配置项,可以在这里查看


实例

from flask import Flask
import config
app = Flask(__name__)
app.config.from_object(config)

@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.debug = True
    app.run()

11【Flask URL】URL中两种方式传参

URL与函数的映射:
从之前的helloworld.py文件中,我们已经看到,一个URL要与执行函数进行映射,使用的是@app.route装饰器。@app.route装饰器中,可以指定URL的规则来进行更加详细的映射,比如现在要映射一个文章详情的URL,文章详情的URL是/article/id/,id有可能为1、2、3…,那么可以通过以下方式:

   @app.route('/article/<id>/')
   def article(id):
       return '%s article detail' % id

其中,尖括号是固定写法,语法为,variable默认的数据类型是字符串。如果需要指定类型,则要写成converter:variable,其中converter就是类型名称,可以有以下几种:

  • string: 默认的数据类型,接受没有任何斜杠/的字符串。
  • int: 整形
  • float: 浮点型。
  • path: 和string类似,但是可以传递斜杠/
  • uuid: uuid类型的字符串。
  • any:可以指定多种路径,这个通过一个例子来进行说明:
  @app.route('/<any(article,blog):url_path>/')
  def item(url_path):
      return url_path

多个url 访问同一个视图函数
Flask视图和URL_python_05

以上例子中,item这个函数可以接受两个URL,一个是/article/,另一个是/blog/。并且,一定要传url_path参数,当然这个url_path的名称可以随便。


如果不想定制子路径来传递参数,也可以通过传统的?=的形式来传递参数,例如:/article?id=xxx,这种情况下,可以通过

request.args.get('id')

来获取id的值。

如果是post方法,则可以通过

request.form.get('id')

来进行获取。


12【Flask URL】url_for使用详解(反转为URL)

构造URL(url_for):
一般我们通过一个URL就可以执行到某一个函数。如果反过来,我们知道一个函数,怎么去获得这个URL呢?url_for函数就可以帮我们实现这个功能。url_for()函数接收两个及以上的参数,他接收函数名作为第一个参数,接收对应URL规则的命名参数,如果还出现其他的参数,则会添加到URL的后面作为查询参数。

通过构建URL的方式而选择直接在代码中拼URL的原因有两点:

1.将来如果修改了URL,但没有修改该URL对应的函数名,就不用到处去替换URL了。
2.url_for()函数会转义一些特殊字符和unicode字符串,这些事情url_for会自动的帮我们搞定。

下面用一个例子来进行解释:

  from flask import Flask,url_for
    app = Flask(__name__)

    @app.route('/article/<id>/')
    def article(id):
        return '%s article detail' % id

    @app.route('/')
    def index(request):
        print(url_for("article",id=1))
        return "首页"

在访问index的时候,会打印出/article/1/

实例

from flask import Flask,url_for
import config
app = Flask(__name__)
app.config.from_object(config)

@app.route('/')
def hello_world():
    print(url_for('my_list'))
    return 'Hello major!'

@app.route('/list/')
def my_list():
    return 'my list!'


if __name__ == '__main__':
    app.debug = True
    app.run()

Flask视图和URL_字符串_06

13【Flask URL】必会的小细节知识

自定义URL转换器:

刚刚在URL映射的时候,我们看到了Flask内置了几种数据类型的转换器,比如有int/string等。如果Flask内置的转换器不能满足你的需求,此时你可以自定义转换器。自定义转换器,需要满足以下几个条件:

1.转换器是一个类,且必须继承自werkzeug.routing.BaseConverter。

2.在转换器类中,实现to_python(self,value)方法,这个方法的返回值,将会传递到view函数中作为参数。

3.在转换器类中,实现to_url(self,values)方法,这个方法的返回值,将会在调用url_for函数的时候生成符合要求的URL形式。

比如,拿一个官方的例子来说,Reddit可以通过在URL中用一个加号(+)隔开社区的名字,方便同时查看来自多个社区的帖子。比如访问“www.reddit.com/r/flask+lisp/”的时候,就同时可以查看flask和lisp两个社区的帖子,现在我们自定义一个转换器来实现这个功能:

#coding: utf-8
from flask import Flask,url_for
from werkzeug.routing import BaseConverter

class ListConverter(BaseConverter):
    def __init__(self,url_map,separator='+'):
        super(ListConverter,self).__init__(url_map)
        self.separator = separator

    def to_python(self, value):
        return value.split(self.separator)

    def to_url(self, values):
        return self.separator.join(BaseConverter.to_url(self,value) for value in values)  

app.url_map.converters['list'] = ListConverter

@app.route('/community1/<list:page_names>')
def community1(page_names):
    return '%s+%s' % tuple(page_names)

@app.route('/community2/<list('|'):page_names>/')
def community2(page_names):
    return "%s|%s" % tuple(page_names)

communityu1使用的是默认的+号进行连接,而第二种方式使用了|进行连接。

指定URL末尾的斜杠:

有些URL的末尾是有斜杠的,有些URL末尾是没有斜杠的。这其实是两个不同的URL。

举个例子:

 @app.route('/article/')
 def articles():
     return '文章列表页'

上述例子中,当访问一个结尾不带斜线的URL:/article,会被重定向到带斜线的URL:/article/上去。但是当我们在定义article的url的时候,如果在末尾没有加上斜杠,但是在访问的时候又加上了斜杠,这时候就会抛出一个404错误页面了:

@app.route("/article")
def articles(request):
    return "文章列表页面"

以上没有在末尾加斜杠,因此在访问/article/的时候,就会抛出一个404错误

指定HTTP方法:

在@app.route()中可以传入一个关键字参数methods来指定本方法支持的HTTP方法,默认情况下,只能使用GET请求,看以下例子:

@app.route('/login/',methods=['GET','POST'])
def login():
    return 'login'

以上装饰器将让login的URL既能支持GET又能支持POST。

14【Flask URL】重定向详解

页面跳转和重定向:

重定向分为永久性重定向和暂时性重定向,在页面上体现的操作就是浏览器会从一个页面自动跳转到另外一个页面。比如用户访问了一个需要权限的页面,但是该用户当前并没有登录,因此我们应该给他重定向到登录页面。

  • 永久性重定向:http的状态码是301,多用于旧网址被废弃了要转到一个新的网址确保用户的访问,最经典的就是京东网站,你输入www.jingdong.com的时候,会被重定向到www.jd.com,因为jingdong.com这个网址已经被废弃了,被改成jd.com,所以这种情况下应该用永久重定向。
  • 暂时性重定向:http的状态码是302,表示页面的暂时性跳转。比如访问一个需要权限的网址,如果当前用户没有登录,应该重定向到登录页面,这种情况下,应该用暂时性重定向。

在flask中,重定向是通过flask.redirect(location,code=302)这个函数来实现的,location表示需要重定向到的URL,应该配合之前讲的url_for()函数来使用,code表示采用哪个重定向,默认是302也即暂时性重定向,可以修改成301来实现永久性重定向。

以下来看一个例子,关于在flask中怎么使用重定向:

from flask import Flask,url_for,redirect

 app = Flask(__name__)
 app.debug = True

 @app.route('/login/',methods=['GET','POST'])
 def login():
     return 'login page'

 @app.route('/profile/',methods=['GET','POST'])
 def profile():
     name = request.args.get('name')

     if not name:
     # 如果没有name,说明没有登录,重定向到登录页面
         return redirect(url_for('login'))
     else:
         return name