基础的准备

1. 使用的python版本 python3.6

2. pycharm编辑器

3. 安装python虚拟环境:

python中的虚拟环境:

python中的虚拟环境相当于一个抽屉,在这个抽屉中安装的任何python包都不会影响到其他的抽屉。

通过pip install virtualenv来安装python的虚拟环境,如果安装出现下面的错误(Read time out,就是下载连接超时,更换到国内的镜像源即可)

更换到国内镜像源有两种方法:

a. 通过安装命令指定镜像源

b. 同构修改python中的配置文件,永久的修改下载镜像源

这里选择通过安装命令临时修改镜像源:

pip install virtualenv -i https://pypi.douban.com/simple/

安装virtualenvwrapper,这个软件包可以使得管理虚拟环境更加的简单,不用再到某个目录下通过virtualenv来创建虚拟环境,并且激活的时候也不不用到特定的目录下去

pip install virtualenvwrapper-win -i https://pypi.douban.com/simple/

virtualenvwrapper的基本使用:

1. 创建虚拟环境

mkvirtualenv flask-env

2. 切换到某个虚拟环境(进入虚拟环境)

workon flask-env

3. 退出当前虚拟环境

deactivate

4. 删除某个虚拟环境

rmvirtualenv flask-env

5. 列出所有虚拟环境

lsvirtualenv

6. 进入虚拟环境所在的目录

cdvirtualenv

7. 修改虚拟环境的路径,

在环境变量->系统变量中添加一个参数WORKON_HOME,将这个参数的值设定为你需要的路径

8. 创建虚拟环境的时候指定python的版本‘

mkvirtualenv --python=D:/Python36/python.exe flask-env

URL组成部分详解:

URL是Uniform Resource Locator的简写,统一资源定位符。

一个URL由以下几部分组成:
scheme://host:port/path/?query-string=xxx#anchor

scheme:代表的是访问的协议,一般为http或者https以及ftp等。
host:主机名,域名,比如www.douban.com。
port:端口号。当你访问一个网站的时候,浏览器默认使用80端口。
path:查找路径,比如:www.jianshu.com/trending/now,后面的trending/now就是path。
query-string:查询字符串,比如:www.baidu.com/s?wd=python,后面的wd=python就是查询字符串。
anchor:锚点,后台一般不用管,前端用来做页面定位的。比如:

Web服务器:负责处理http请求,响应静态文件,常见的有Nginx

应用服务器:负责处理逻辑的服务器,例如编写的python代码,是不能直接通过nginx这种web服务器来处理的,只能通过应用服务器来处理,常见的应用服务器有uwsgi、tomcat等。

web应用框架:一般使用某种语言,封装了常用的web功能的框架就是web应用框架,flask、Django框架都是web应用框架。

Flask简介:

flask是一款非常流行的python web框架,它是一个微框架,具有简洁的特点,且flask和相关的依赖设计的非常优秀。

打开创建的虚拟环境:创建第一个flask程序

from flask import Flaskapp = Flask(__name__)
# __name__参数的所用:
# 1. 可以规定模板和静态文件的查找路径
# 2. 以后如果flask的插件,比如flask-migrate, flask-sqlalchemy如果报错,
# 那么flask可以通过这个参数找到具体的错误位置# @app.route()的作用是将url映射到对应的视图函数上面
@app.route('/')
def hello_world():return 'Hello vv World!'if __name__ == '__main__':app.run(port=8000)     # app.run()是flask中的一个测试服务器

flask的debug模式

在pycharm中,在程序中开始debug=True之后,需要在IDE中下面的位置:

点击Edit Configurations, 然后再勾选FLASK_DEBUG,这样就可以开启debug模式

1. 开始debug模式,在代码中如果抛出了异常,在浏览器的页面中可以看到具体错误信息以及错误代码

2. 如果不开启debug模式,则看不到相应的错误信息

3. 开启debug模式之后,再修改完代码后,不用再重新手动运行代码,按下CTRL+S,flask会自动将修改后的代码加载。此时只需要重新刷新网页即可。

flask中的配置文件

一般再开发中,我们会将整个项目的配置放到一个文件中,这样会便于整个项目的管理,可以在flask目录下新建一个config.py文件,用于存放整个项目的所有配置:

1. 首先import config

app.config.from_object(config)加载配置文件

2. 在不想import config.py文件的时候,可以通过另一种方式导入:

参数silent=false:如果加载的配置文件不存在,就会报错,如果silent=true,则即使加载的文件不存在,也不会报错

app.config.from_pyfile("config.py", silent=False)   # 加载配置文件config, 也可以加载普通的txt文件

---------------------------------------------------------------------------------------------

URL与视图函数的映射

如何在url中传递参数:

在flask中,通过装饰器app.route()将url与视图函数映射起来

from flask import Flaskapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False)   # 加载配置文件config, 也可以加载普通的txt文件@app.route('/')
def hello_world():return 'Hello World!'@app.route('/list/')
def article_list():return "article list"if __name__ == '__main__':app.run(debug=True)     # 开启debug模式

如果需要在URL中传递参数,则可以按照如下的方式进行:同时视图函数也必须定义同名的形参

@app.route('/article/<article_id>/')   # url最好以/结尾
def article_detail(article_id):return "The article id is %s" % article_id

如果传递的参数的数据类型是某一个确定的类型,则可以进行指定:

@app.route('/article/<int:article_id>/')   # url最好以/结尾
def article_detail(article_id):return "The article id is %s" % article_id

其他的数据类型还有:

还有一种特殊的数据类型: uuid  通用唯一识别码(Universally Unique Identifier)

这种字符串中的每一个能够保证唯一性,所以可以作为数据库中的主键进行使用,在python中可以通过uuid模块生成uuid

import uuid
print(uuid.uuid4())

为了保证UUID的唯一性,规范定义了包括网卡MAC地址、时间戳、名字空间(Namespace)、随机或伪随机数、时序等元素,以及从这些元素生成UUID的算法。UUID的复杂特性在保证了其唯一性的同时,意味着只能由计算机生成。UUID是不能人工指定的,除非你冒着UUID重复的风险。UUID的复杂性决定了“一般人“不能直接从一个UUID知道哪个对象和它关联。

例如,在某网站需要访问博客或者用户,那么可以按照一般的方法,定义两个视图函数

# .../blog/<id>/    访问博客

#.../user/<id>/      访问某一位作者

还可以按照另一种方式实现,将两个url放到一个当中,可以通过any()实现

@app.route('/<any(blog, user):url_pass>/<id>/')   # url_pass用于存放blog或者user
def get_detail(url_pass, id):if url_pass == "blog":return "You get blog detail %s" % idelse:return "You get user detail %s" % id

此时:

http://127.0.0.1:5000/blog/12/

http://127.0.0.1:5000/user/12/

两个链接均可以映射到同一个视图函数

总结:

传递参数的数据类型可以总结为:
int, float, string, path, uuid, any

获取客户端发送的参数

在get方法中,用户会通过查询字符串的方式向服务端传送数据,在服务端,flask可以按照以下的方式获取参数

from flask import Flask
from flask import requestapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False)   # 加载配置文件config, 也可以加载普通的txt文件@app.route('/')
def hello_world():return 'Hello World!'@app.route('/day/')
def get_day():username = request.args.get("user")passwd = request.args.get("password")return "User: %s password: %s" % (username, passwd)if __name__ == '__main__':app.run(debug=True)     # 开启debug模式

则通过url获取的参数如下:

所以接受用户传递的参数有两种方式:
1. 通过path的形式,将参数嵌入到路径当中,进行参数传递

2. 使用查询字符串的方式,即通过“?key=value”的形式

采用第一种形式有利于搜索引擎优化(SEO),而第二种方式不利于搜索引擎优化

flask: url_for使用详解:

app.route()用于将url映射到视图函数,而url_for则正好与之相反,可以通过视图函数找到对应的url

from flask import Flask
from flask import url_forapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False)   # 加载配置文件config, 也可以加载普通的txt文件@app.route('/')
def hello_world():print(url_for("my_list"))   # 视图函数对应的url  输出/list/return 'Hello World!'@app.route('/list/')
def my_list(page):return "My list is here %d" % page if __name__ == '__main__':app.run(debug=True)     # 开启debug模式

还可以获取url中具有参数的视图函数的url:

from flask import Flask
from flask import url_forapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False)   # 加载配置文件config, 也可以加载普通的txt文件@app.route('/')
def hello_world():print(url_for("my_list", page=1))   # 视图函数对应的url  输出/list/return 'Hello World!'@app.route('/list/<page>')
def my_list(page):return "My list is here %d" % pageif __name__ == '__main__':app.run(debug=True)     # 开启debug模式

url_for的优点:

1. 如果修改了url,就不用去手动拼接替换url

2. url_for会自动处理特殊字符,例如\,会自动对\进行编码,不用去手动处理

url_for中的next参数,相当于给url中添加一个查询字符串,字符串的形式为 ?next="xxx"

自定义url转换器

例如,在一个url中传递的参数中有手机号码,为了对手机号码这一参数进行严格的限制,需要自定义url转换器:

所有上述介绍的转换器的定义都在一个称为BaseConverter的包中:

from werkzeug.routing import BaseConverter

在这个包中,不同的转换器都是继承自基类BaseConverter

例如:

class UnicodeConverter(BaseConverter):"""This converter is the default converter and accepts any string butonly one path segment.  Thus the string can not include a slash.This is the default validator.Example::Rule('/pages/<page>'),Rule('/<string(length=2):lang_code>'):param map: the :class:`Map`.:param minlength: the minimum length of the string.  Must be greateror equal 1.:param maxlength: the maximum length of the string.:param length: the exact length of the string."""def __init__(self, map, minlength=1, maxlength=None, length=None):BaseConverter.__init__(self, map)if length is not None:length = "{%d}" % int(length)else:if maxlength is None:maxlength = ""else:maxlength = int(maxlength)length = "{%s,%s}" % (int(minlength), maxlength)self.regex = "[^/]" + lengthclass NumberConverter(BaseConverter):"""Baseclass for `IntegerConverter` and `FloatConverter`.:internal:"""weight = 50def __init__(self, map, fixed_digits=0, min=None, max=None, signed=False):if signed:self.regex = self.signed_regexBaseConverter.__init__(self, map)self.fixed_digits = fixed_digitsself.min = minself.max = maxself.signed = signeddef to_python(self, value):if self.fixed_digits and len(value) != self.fixed_digits:raise ValidationError()value = self.num_convert(value)if (self.min is not None and value < self.min) or (self.max is not None and value > self.max):raise ValidationError()return valuedef to_url(self, value):value = self.num_convert(value)if self.fixed_digits:value = ("%%0%sd" % self.fixed_digits) % valuereturn str(value)@propertydef signed_regex(self):return r"-?" + self.regexclass IntegerConverter(NumberConverter):"""This converter only accepts integer values::Rule("/page/<int:page>")By default it only accepts unsigned, positive values. The ``signed``parameter will enable signed, negative values. ::Rule("/page/<int(signed=True):page>"):param map: The :class:`Map`.:param fixed_digits: The number of fixed digits in the URL. If youset this to ``4`` for example, the rule will only match if theURL looks like ``/0001/``. The default is variable length.:param min: The minimal value.:param max: The maximal value.:param signed: Allow signed (negative) values... versionadded:: 0.15The ``signed`` parameter."""regex = r"\d+"num_convert = intclass FloatConverter(NumberConverter):"""This converter only accepts floating point values::Rule("/probability/<float:probability>")By default it only accepts unsigned, positive values. The ``signed``parameter will enable signed, negative values. ::Rule("/offset/<float(signed=True):offset>"):param map: The :class:`Map`.:param min: The minimal value.:param max: The maximal value.:param signed: Allow signed (negative) values... versionadded:: 0.15The ``signed`` parameter."""regex = r"\d+\.\d+"num_convert = floatdef __init__(self, map, min=None, max=None, signed=False):NumberConverter.__init__(self, map, min=min, max=max, signed=signed)

系统中已经预定义的转换器如下所示:

#: the default converter mapping for the map.
DEFAULT_CONVERTERS = {"default": UnicodeConverter,"string": UnicodeConverter,"any": AnyConverter,"path": PathConverter,"int": IntegerConverter,"float": FloatConverter,"uuid": UUIDConverter,
}

所以,可以按照转换器的定义方法,自定义手机号码转换器,定义一个视图函数,并且将电话号码作为参数传入到url中:

from flask import Flask
from werkzeug.routing import BaseConverter
import reapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False)   # 加载配置文件config, 也可以加载普通的txt文件# 自定义转换器
class TelephoneConverter(BaseConverter):regex = r'1[0-9]{9}[0-9]'app.url_map.converters["tel"] = TelephoneConverter    # 将自定义的转换器添加到预定义的转换器中@app.route('/')
def hello_world():return 'Hello World!'@app.route('/telephone/<tel:phone>/')
def user_phone(phone):return "The user phone is %s" % phoneif __name__ == '__main__':app.run(debug=True)     # 开启debug模式

总结:

1. 实现自定义转换器,必须实现一个类,继承自基类BaseConverter

2. 在自定义的类中,必须重写正则表达式regex

3. 将自定义的类映射到app.url_map.converters["tel"] =  xxx

转换器除了对传入到url中的参数的数据类型可以限制外,还具有真正的转换功能,例如,对传入到url中的参数进行解析并返回,此时,如果对url传入某种格式的参数,那个url对应的视图函数此时接受到的参数,实际上是经过Converter转换过的参数,可以直接使用。例如,对于 /blog/ai+c/表示需要查找分类为AI和C语言的所有博客:此时,就可以利用Converter对传入的参数ai+c进行转换,使得视图函数得到的参数为[ai, c],需要实现这种功能,需要在Converter中实现to_python()方法:Converter中还有一个方法,即to_url(),这个方法实现的功能正好与to_python()方法相反,通过实现to_url方法,能够获取到带参数的视图函数对应的url

from flask import Flask, url_for
from werkzeug.routing import BaseConverterapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False)   # 加载配置文件config, 也可以加载普通的txt文件# 自定义转换器
class TelephoneConverter(BaseConverter):regex = r'1[0-9]{9}[0-9]'# 自定义转换器
class ListConverter(BaseConverter):def to_python(self, value):      # 需要实现转换功能,必须实现to_python方法,将url中的参数经过解析传递给视图函数if "+" in value:res = value.split("+")else:res = [value]return resdef to_url(self, value):         # 会在调用url_for的时候生成符合要求的url形式return "+".join(value)app.url_map.converters["tel"] = TelephoneConverter    # 将自定义的转换器添加到预定义的转换器中
app.url_map.converters["list"] = ListConverter        # List 转换器@app.route('/')
def hello_world():print(url_for("get_blog", category=["aa", "bb"]))return 'Hello World!'@app.route('/telephone/<tel:phone>/')
def user_phone(phone):return "The user phone is %s" % phone@app.route('/blog/<list:category>/')
def get_blog(category):res = ""for x in category:res = res + x + "|"return "The blog %s" % res[:-1]if __name__ == '__main__':app.run(debug=True)     # 开启debug模式

转换的结果:

例如,输入的url中包含参数,/a+b/,转换器可以对这个参数提前进行解析,使得传递给视图函数的是解析过的参数[a, b]

to_url的效果:

例如视图函数get_blog( ),通过url_for生成他的url是,可以将传入的参数进行转换,在嵌入到url中,得到的url中包含/a+b/

其他的小细节:

1. 在局域网中让其他电脑能访问到我的网站:
    修改host="0.0.0.0"

2. 指定端口号

flask项目,默认使用的是5000端口,可以通过port=8000来设置端口号

3. url唯一性

在定义url的时候,要在最后加上/,同时搜索引擎会将加/和不加/的url视为两个url,但实际上这是同一个url,因此这样不利于SEO

4. get请求与post请求

get: 只会在服务器上获取资源,不会影响服务器的状态,这种请求方式推荐使用get请求。get请求会将请求参数放到url当中 。

post: 会给服务器提交一些数据以及文件,会对服务器的状态产生影响。这种条件下推荐post请求

5. flask中,默认的请求方式为GET请求,可以通过methods参数进行设置

重定向:

重定向分为永久重定向和暂时重定向,在页面上体现的操作就是浏览器会从一个页面跳转到另一个页面。比如在访问一个网站的过程中,用户访问了一个需要登陆的页面,当时用户当前没有登陆,所以需要给用户跳转到登陆界面,让其重新登陆才可以。

永久重定向:http的状态码是301,多用于旧的网址被废弃,用户需要转到一个新的网址。例如在浏览器访问www.jingdong.com,会被永久重定向到www.jd.com,因为网址www.jingdong.com已被废弃。

暂时重定向:http的状态码是302,表示页面暂时性的跳转了,比如访问一个需要权限的网址,如果用户当前没有登陆,应该暂时重定向到登陆页面。

在flask中,通过redirect(locaton, code=302)来实现重定向的。

from flask import Flask, url_for, request, redirectapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False)   # 加载配置文件config, 也可以加载普通的txt文件@app.route('/')
def hello_world():return 'Hello Wold!'@app.route('/login/')   # 登陆页面
def login():return "Login page"@app.route('/profile/')  # 用户详情页
def profile():name = request.args.get("name")if name:return "User: %s" % nameelse:return redirect(url_for("login"), code=302)if __name__ == '__main__':app.run(debug=True)     # 开启debug模式

视图函数Response返回值详解:

视图函数应该返回什么样的值?

视图函数的返回值会被自动转化为一个响应对象,flask的转化过程如下:

1. 如果返回值是Response对象,则直接返回

2. 返回值是一个字符串,那么flask会创建一个werkzeug.wrappers.Response对象,Response将该字符串作为主体,状态码为200,MIME类型为text/html.然后返回该Response对象

3. 如果返回的是一个元组,元组中的数据类型是(response,status,headers)。status值会覆盖默认的200状态码,headers可以是一个列表或者字典,作为额外的消息头。

4. 如果以上条件都不满足,flask会假设返回值是一个合法的WSGI应用程序,并通过Response.force_type()转换为一个请求对象。

flask = werkzeug(处理网络请求相关的) + sqlalchemy(处理数据库相关) + jinja2(html模板相关)

自定义响应:

Restful-API都是通过JSON的形式进行传递的,如果后台跟前台进行交互的时候,所有的url都是发送JSON数据,则可以定义一个叫做JSONResponse的类来代替Flask自带的Response类。

自定义响应必须满足以下三个条件:

1. 必须继承自Response类

2. 必须实现force_type(cls, rv, environ=None)

3.必须指定app.response_class为自定义的Response

4. 如果视图函数返回的数据不是字符串,也不是元组,也不是Response对象,那么就会将返回值传递给force_type,然后再将response_type的返回值返回给前端。

from flask import Flask, Response, jsonifyapp = Flask(__name__)
app.config.from_pyfile("config.py", silent=False)   # 加载配置文件config, 也可以加载普通的txt文件# 将视图函数中返回的字典,转换为JSON对象,然后返回
class JSONResponse(Response):@classmethoddef force_type(cls, response, environ=None):"""这个方法只有视图函数返回,非字符串,非元组,非Response对象的时候才会调用:param response::param environ::return:"""if isinstance(response, dict):# jsonify将字典转换为json对象,且包装成Response对象response = jsonify(response)return super(JSONResponse, cls).force_type(response, environ)app.response_class = JSONResponse@app.route('/')
def hello_world():return 'Hell Wold!'@app.route('/list/')
def list_1():return {"name": "lili", "age": 26}     # 此时返回的是字典,所以会调用上面的JSONResponse方法if __name__ == '__main__':app.run(debug=True)     # 开启debug模式

视图函数可以返回的类型:

1. 可以返回字符串,flask底层会将这个字符串包装成Response对象

2. 可以返回元组,元组的形式是:(响应体,状态码,头部信息),返回的元组其实在底层也是封装成Response对象

3. 可以返回Response及其子类

------------------------------------------------------------------------------------------------------------------------------

Web后端学习笔记 Flask(1)基础知识相关推荐

  1. Web后端学习笔记Flask(2)模板

    模板渲染: 在flask中,视图函数可以直接通过render_template进行模板渲染.在flask中,模板文件是存放在template文件夹中:在调用模板文件的时候,模板文件的路径从templa ...

  2. Web后端学习笔记 Flask (5) 数据库

    MySql数据库安装:省略 SQLAlchemy介绍和基本使用: 数据库是开发网站的基础,,在Flask中,支持的数据库有:MySql,PostgreSql,SQLite,Redis,MongoDB来 ...

  3. Web后端学习笔记 Flask(10)CSRF攻击原理

    CSRF(Cross Site Request Forgery,跨站域请求伪造)是一种网络的攻击方式,它在2007年曾被列为互联网20大安全隐患之一. CSRF攻击的原理: 网站是通过cookie实现 ...

  4. Web后端学习笔记 Flask(9)cookie and session

    Flask_wtf除了可以做表单验证,模板渲染之外,还可以防御CSRF攻击.要了解CSRF攻击的原理,首先需要了解cookie和session的知识点. cookie:在网站中,HTTP请求是无状态的 ...

  5. Web后端学习笔记 Flask(7)数据库

    高级查询: 1. group_by 根据某个字段进行分组,比如说需要根据某个字段分组,来统计每组有多少人. 2. having having是对查询结果进一步过滤,比如只想看到未成年人的数量,那么首先 ...

  6. Web后端学习笔记 Flask(11)Local线程隔离对象

    flask中的上下文:应用上下文和请求上下文 1. 在flask中,是通过request对象获取用户提交的数据,但是在整个程序运行中,只有一个request对象.在实际应用场景中,会有多个用户同时进行 ...

  7. Web后端学习笔记 Flask(8) WTForms 表单验证,文件上传

    Flask-WTF是简化了WTForms操作的一个第三方库.WTForms表单的两个主要功能是验证用户提交数据的合法性以及渲染模板.同时还包含一些其他的功能.例如CSRF保护,文件上传等功能,安装fl ...

  8. Web后端学习笔记 Flask(4)视图函数

    Flask中的视图函数以及视图类: 添加视图函数还可以通过下面的方式add_url_rule进行: app.add_url_rule(rule,  endpoint,  view_func): rul ...

  9. Web后端学习笔记 Flask (14)redis

    redis介绍: redis是一种noSQL数据库,它的数据是保存在内存中,同时,redis可以定时把内存中的数据同步到磁盘,即可以将数据持久化,并且它比memcached支持更多的数据结构,stri ...

最新文章

  1. Restful API的设计思路
  2. 自动化WiFI钓鱼工具——WiFiPhisher源码解读
  3. 【转】路由转发过程的IP及MAC地址变化
  4. 《C++ Primer》7.2节练习
  5. python报表自动化系列 - python中索引pandas.DataFrame的内容
  6. 减小pdf大小 打印 低分辨率
  7. idea插件JRebel激活
  8. 根据身份证判断男女(通用)
  9. 广域通信网知识点笔记
  10. 2021-2027全球与中国卸扣式绝缘子市场现状及未来发展趋势
  11. 利用Spire实现对Word模板的指定文字替换(文字、图片、表格)
  12. 高通芯片联机读取修改串码 meid ESN wifi 蓝牙 sn等参数的操作解析{二}
  13. 我的世界服务器修改地图,我的世界如何修改地图?
  14. 新浪微博Android客户端开发之OAuth认证篇
  15. IntelliJ IDEA--配置导入导出
  16. ————《metasploit 魔鬼训练营》学习笔记序言
  17. ROS2机器人-C++和Python怎么选
  18. 要活 102 年,阿里凭借的是什么?
  19. Wireshark解密https数据
  20. 临汾空气质量排名垫底是因不努力?生态环境部回应

热门文章

  1. Windwos命令工作笔记002---windows下tree命令列出文件目录打印到文件中_过滤文件不知道怎么做啊
  2. 面试常考题目之atoi的实现
  3. php sort函数,php中sort函数的功能起什么作用呢?
  4. 微信小程序上传接口php,微信小程序API 上传、下载
  5. 随想录(什么是软件架构师)
  6. dlut-KFQ人工智能导论答案1
  7. python中int什么意思_python3中int(整型)的使用教程
  8. python函数的使用场景_详解python中strip函数的使用场景
  9. oracle ogg和adg,ORACLE12C ADG和OGG的搭配使用
  10. html 设置两个标签的相对距离_如何准确计算一div相对另一div的相对距离?