flask基础之一
flask基础之一
hello world
#从flask这个包中导入Flask这个类
#Flask这个类是项目的核心,以后的很多操作都是基于这个类的对象
#注册url,注册蓝图都是这个类的对象
from flask import Flask
#创建一个Flask对象,传递__name__这个参数进去
#__name__这个参数的作用:
# 1.规定模板和静态资源的路径
# 2.以后的一些Flask插件,比如Flask_migrate,Flask_SQLAlchemy报错的话,哪么Flask就会通过这个参数找到具体的报错位置
app = Flask(__name__)
# @app.route()是一个装饰器,将对应的“/”路径应用到hello_world()这个函数上面
# 在访问“/”的时候在页面上返回Hello World
@app.route('/')
def hello_world():
return 'Hello World!'
# 如果作为一个主文件运行,哪么执行app.run()方法,也就是启动这个网站
if __name__ == '__main__':
app.run()
debug模式
- 为什么要开启DEBUG模式?
- 如果开启了debug模式,name代码在调试过程中出现了异常,在浏览器页面中可以看到具体的报错信息,以及具体的错误代码位置,方便开发者调试。
- 如果flask开启了debug模式,name以后再python中修改任何代码,只要在pycharm中使用ctrl+s即可保存重载,不需要手动去重载程序
- 如何配置debug模式:
app.run()
app.run(debug=True)
app.debug
app.debug = True
配置信息方式(使用参数形式的方式)
app.config.update[DEBUG=True]
#其实也就是update了config字典
通过配置文件的形式
- 创建一个config.py的配置文件,写入
DEBUG = True
- 然后在你的app.py文件中写入
app.config.from_object(config) #即可读取配置文件中的DEBUG=True
debug PIN码
D:\MyDevSoftInstallDir\Python3\python3.exe D:/myflask/base/base.py
* Restarting with stat
* Debugger is active!
* Debugger PIN: 177-952-649
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
然后在页面上调试代码的时候用到。
也是为了安全考虑。
配置文件两种方式详解
- 第一种方式:
在项目主路径下创建config.py
DEBUG=True
然后在主项目里面去读取config.py
里面的配置:
from flask import Flask
import config
app = Flask(__name__)
app.config.from_object(config)
- 第二种方式:直接读取文件的形式,也可以是普通的txt文件形式;这种方式不需要直接
import config
在项目主路径下创建config.py
DEBUG=True
然后在主项目里面去读取config.py
里面的配置:
from flask import Flask
app = Flask(__name__)
app.config.from_pyfile('config.py',silent=True) #静默模式加载配置文件(找不到配置文件不报错),文件的后缀名不可少
url与视图函数的映射
- 传递参数:
传递参数的语法是
/<参数类型:参数名称>/
,然后在视图函数中也要定义同名的参数
- 参数的数据类型
- string:只接受字符串,没有任何“/或者”的文本
- int:只接受整数
- float:只接受浮点数,整数都不行哈
- path:和
string
类似,但是接受斜杠- uuid:只有接受符合
uuid
的字符赤岸,一般用作表的主键- any:可以指定多种路径
接收用户传递参数的方式:
- 使用path的方式(将参数嵌入到路径中)
- 使用查询字符串的形式 (也就是通过
?key=value
的形式传递的,只能通过request.args.get的方式来获取)
如果页面想要做SEO优化的话,那么推荐使用path
的形式,反之就是查询字符串的形式
练习
from flask import Flask,request
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route('/list/')
def article_list():
return 'article list!'
@app.route('/p1/<article_id1>')
def article_detail(article_id1):
return "请求的文章是:%s" %article_id1
@app.route('/p2/<string:article_id2>')
def article_detail2(article_id2):
return "请求的文章是:%s" %article_id2
@app.route('/p3/<int:article_id3>')
def article_detail3(article_id3):
return "请求的文章是:%s" %article_id3
@app.route('/p4/<path:article_id4>')
def article_detail4(article_id4):
return "请求的文章是:%s" %article_id4
# import uuid
# print(uuid.uuid4())
@app.route('/p5/<uuid:article_id5>') #数据的唯一性,长度较长,有损效率(一般在用户表中使用)6a9221f6-afea-424a-a324-8ceaa5bdfc98
def article_detail5(article_id5):
return "请求的文章是:%s" %article_id5
@app.route('/p6/<any(blog,user):url_path>/<id>/')
def detail(url_path,id):
if url_path == "blog":
return "博客详情 %s" %id
else:
return "用户详情 %s" %id
#通过问号形式传递参数
@app.route('/d/')
def d():
wd = request.args.get('wd') #获取浏览器传递参数
return '通过查询字符串的方式传递的参数是,%s'%wd #请求http://127.0.0.1:8080/d/?wd=php
if __name__ == '__main__':
app.run(debug=True,host='0.0.0.0',port=8080)
url_for
- 将视图函数反转回URL,跟app.route相反
- URL的更新大于视图函数,所以在大规模项目中比较实用
* 基本使用 :
url_for
的第一个参数是视图函数的函数名对应的字符串(endpoint),后面的参数就是你传递给url
;如果传递的参数在url
中已经定义了,那么这个参数就会被当成path的值传递给url
;如果这个参数没有在url
中定义,那么将变成查询字符串的形式
from flask import Flask,url_for,request
app.route('/')
return url_for('my_list',page=1,count=2) #这样的话就会在页面上构建出/post/list/1/?count=2的信息
app.route('/post/list/<page>/')
def my_list():
return 'my list'
- 为什么需要
url_for
?
如果将来要修改
URL
,但没有修改URL
对应的函数名,就不用到处去替换URL了。URL
会自动处理特殊字符(转义成十六进制),不需要手动去处理
from flask import Flask,url_for,request
@app.route('/')
def hello_world():
return url_for('login',next='/current') #页面返回/login/?next=%2Fcurrent登录前的信息
# print(url_for('my_list',page=1,count=200))
# return 'hello world'
@app.route('/login/')
def login():
# next = request.args.get('next') #登录前的信息,在登陆之后仍旧保持
return 'login'
@app.route('/list/<page>')
def my_list():
return 'my list'
@app.route('/detail/<id>/')
def detail():
return 'detail'
if __name__ == '__main__':
app.run(debug=True)
自定义url转换器
- url的参数转换成满足自己需求的数据类型
自定义url
转换器的方式:
- 实现一个类,继承
BaseConverter
- 在自定义的类中重写
regex
,也就是这个变量的正则表达式 - 将自定义的类映射到
app.url_map.converters
上。
实现用户访问/posts/a+bto_python
的作用
这个方法的返回值会传到view函数中作为参数to_url
的作用
这个方法的返回值会调用url_for来生成符合要求的url形式
from flask import Flask,url_for
from werkzeug.routing import BaseConverter
app = Flask(__name__)
#手机号码正则
class TelephoneConveter(BaseConverter):
regex = r'1[85734]\d{9}'
app.url_map.converters['tel'] = TelephoneConveter
#用户访问/posts/a+b/
class ListConverter(BaseConverter):
def to_python(self, value):
return value.split("+")
def to_url(self, value):
print(value)
return '+'.join(value)
# return "hello"
app.url_map.converters['list'] = ListConverter
@app.route('/')
def hello_world():
print(url_for('posts',broads=['a','b']))
return 'Hello World!'
@app.route('/user/<int:user_id>/')
def user(user_id):
return "your user id is %d" %user_id
@app.route('/telephone/<tel:my_tel>/')
def my_tel(my_tel):
return "your telephone number is %s"%my_tel
@app.route('/posts/<list:broads>/')
def posts(broads):
# broads = broads.split("+")
return "your posts is %s"%broads
if __name__ == '__main__':
app.run(debug=True)
小细节
在局域网访问站点
app.run(host='0.0.0.0')
指定端口号
默认是5000端口,修改端口如下
app.run(host='0.0.0.0',port=8899 )
ulr唯一
在定义
URL
的时候,尽量在url后面加/
,原因如下:- 如果不加
/
的话浏览器访问这个url的时候会默认加/
,这样的话就访问不到了 - 搜索引擎会将不加
/
的url和加/
的url是两个不同的url,会将其误解。
- 如果不加
GET和POST请求
在网络请求中有许多的请求方式,比如GET
,POST
,DELETE
,PUT
,常用的请求方式如下:
GET
:也就是获取
服务器上的资源,不会修改服务器上的内容。POST
:就是向服务器提交文件或者数据,一般POST会对服务器的状态产生影响。关于参数传递:
GET
:把参数放到URL
中,通过?xx=xxx
的形式传递的,因为会把参数放到url中,所以视力好的话,一眼就可以看到传递的参数。POST
:把参数放到Form Data
中,避免被偷窥到的风险(也有可能通过抓包的方式被窃取),一般不安全的,不晓得提交的内容是否是带病毒的文件。
在
flask
中,route
方法,默认只能使用GET
的方式请求url。如果想要设置自己的请求方式,那就要在methods
中多传递一个请求方式的参数。
实例如下:
创建url_detail的项目,项目结构如下:
├─url_detail.py
├─static
└─templates
|_login.html
- url_detail.py"
from flask import Flask,request,render_template
app = Flask(__name__)
@app.route('/',methods=['GET'])
def hello_world():
return 'Hello World!'
@app.route('/list/',methods=['POST'])
def my_list():
return 'list'
@app.route('/login/',methods=["POST","GET"])
def login():
if request.method == 'GET':
return render_template('login.html')
else:
return "Success"
if __name__ == '__main__':
app.run(debug=True,host='0.0.0.0')
- templates/login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="",method="POST">
<input type="text",name="username">
<input type="text",name="password">
<input type="submit",name="submmit">
</form>
</body>
</html>
URL重定向
也就是从一个页面跳转到另一个页面,也就是重新定位一个方向
分类:
- 永久性重定向:http的状态码是301,多用于旧的网址废弃了要转到一个新的网址,确保用户的访问。最经典的就是
jingdong.com
了 - 暂时性重定向:http的状态码是302,表示页面暂时性被跳转,比如访问一个需要权限的网址,如果当前用户没有登录,应该重定向到登录页面。这种情况的话就是用暂时性重定向。
在flask中,重定向是通过
flask.redirect(location,code=302)
这个函数来实现的,location
指的是需要重定向到的URL
,应该配合之前讲过的url_for()
来是用。code
代表的是什么类型的重定向,默认是302,可以修改成301实现永久重定向。
- 小例子:
from flask import Flask,url_for,redirect,request
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:
return redirect(url_for('login'))
else:
return name
if __name__ == '__main__':
app.run()
这样的话就能访问profile了:
http://127.0.0.1:5000/profile/?name=sss
关于响应
视图函数的返回值会被自动转换成一个响应对象,flask的转换逻辑如下:
- 如果返回的是一个合法的响应对象,则直接返回
- 如果返回的是一个字符串,那么flask会重新创建一个
werkzeug.wrappers.Response
对象。Response
会将该字符串作为主体,状态码为200,MIME
的类型为text/html
,然后返回给Response对象 - 如果返回的是一个元组,元组中的数据类型是
response,status,headers
,status会覆盖默认的200状态码,headers可以是一个字典或者列表。作为额外的消息头 - 如果以上的条件都不满足,flask会假设返回值是一个合法的
WSGI
应用程序,并通过Response.force_type(rv,request.environ)
转换成一个请求对象。 自定义响应:
- 必须继承自
Response
类 - 实现类方法:
force_type
- 必须指定app.response_class为你自定义的Response
- 如果视图函数返回的数据既不是字符串,也不是元组,也不是Response对象,那么会将返回值传给
force_type
,然后将force_type
的返回值返回给前端。
- 必须继承自
#!/usr/bin/python
# -*- coding:utf8 -*-
from flask import Flask,Response,jsonify
import json
app = Flask(__name__)
app.debug = True
#自定义响应
class JSONResponse(Response):
@classmethod
def force_type(cls, response, environ=None):
'''
这个方法只有视图函数返回非字符串,非元组,非Response对象才会调用
:param response:
:param environ:
:return:
'''
print response
print type(response)
if isinstance(response,dict):
#jsonify除了将字典转换成为json对象,还将对象封装成了一个Response对象
response = jsonify(response)
#response = json.dumps(response) #这样转换的话程序启动会报错
return super(JSONResponse,cls).force_type(response,environ) #返回父类信息
app.response_class = JSONResponse
@app.route('/')
#第一种情况
def hello_world():
#Response('Hello World',status=200,mimetype='text/html')
return 'Hello World!'
#第二种情况
@app.route('/list1/')
def list1():
resp = Response('List1')
resp.set_cookie('country','china')
return resp
#第三种情况
@app.route('/list2')
def list2():
return 'list2',200,{'X-Name':'abc'}
@app.route('/list3/')
def list3():
return {"username":"abc","age":11}
if __name__ == '__main__':
app.run(host='0.0.0.0')
flask基础之一的更多相关文章
- flask基础之AppContext应用上下文和RequestContext请求上下文(六)
前言 应用上下文和请求上下文存在的目的,官方文档讲的很清楚,可参考: http://www.pythondoc.com/flask/appcontext.html 应用上下文对象在没有请求的时候是可以 ...
- flask基础之请求处理核心机制(五)
前言 总结一下flask框架的请求处理流程. 系列文章 flask基础之安装和使用入门(一) flask基础之jijia2模板使用基础(二) flask基础之jijia2模板语言进阶(三) flask ...
- flask基础之app初始化(四)
前言 flask的核心对象是Flask,它定义了flask框架对于http请求的整个处理逻辑.随着服务器被启动,app被创建并初始化,那么具体的过程是这样的呢? 系列文章 flask基础之安装和使用入 ...
- flask基础之jijia2模板语言进阶(三)
前言 前面学习了jijia2模板语言的一些基础知识,接下来继续深挖jijia2语言的用法. 系列文章 flask基础之安装和使用入门(一) flask基础之jijia2模板使用基础(二) 控制语句 和 ...
- flask基础之jijia2模板使用基础(二)
前言 在以前前后端不分离的时代,后台程序员往往又当爹又当妈,需要将前端程序员写的h5页面填充模板语言.而jijia2是一门十分强大的python的模板语言,是flask框架的核心模块之一.先简单介绍一 ...
- 笔记-flask基础操作
笔记-flask基础操作 1. 前言 本文为flask基础学习及操作笔记,主要内容为flask基础操作及相关代码. 2. 开发环境配置 2.1. 编译环境准备 安装相关Lib ...
- Flask基础(16)-->WTForms表单创建和简单验证
Flask基础(16)-->WTForms表单创建和简单验证 前言:使用Flask_WTF需要配置参数SECRET_KEYCSRF_ENABLED是为了CSRF(跨站请求伪造)保护.SECRET ...
- Flask基础(14)-->自定义过滤器
Flask基础(13)-->自定义过滤器 什么是过滤器? 过滤器的本质就是函数.有时候我们不仅仅只是需要输出变量的值,我们还需要修改变量的显示,甚至格式化.运算等等,而在模板中是不能直接调用 P ...
- Flask基础(13)-->Flask扩展Flask-Script
Flask基础(12)-->Flask扩展Flask-Script # 前提是安装了Flask-Script # 联网运行 pip install flask-script from flask ...
- Flask基础(06)-->视图常用逻辑
Flask基础(06)-->视图常用逻辑 返回json 重定向:url_for 自定义状态码 返回json:在使用 Flask 写一个接口时候需要给客户端返回 JSON 数据,在 Flask 中 ...
随机推荐
- 四十、python中的生成器和迭代器
A.生成器(包含yield的就是生成器) def func(): print(11) yield 1 print(22) yield 2 print(33) yield 3 print(44) yie ...
- Vue中使用JSX语法
一 项目结构 二 App组件 <template> <div id="app"> <fruit/> </div> </temp ...
- QA的工作职责是什么?
目前不知道,后续一点一点查资料补充吧 QA不管做什么的类型的测试,最基础的功能测试,需要搭建测试环境:进阶部分的性能压力测试,对搭建环境的要求更高:接口功能测试,搭建测试环境,和功能测试的差不多: 测 ...
- EFI系统分区如何删除
U盘或者硬盘被做了系统安装盘. 结果在格式化都是失败,分区也不行. 有了新招 EFI分区是您的系统启动引导的分区,存放引导启动的文件的,因此它是一个操作系统独立的分区,实际上它是UEFI加载的固件和应 ...
- java 对象 json 集合 数组 互转
1.先定义一个类对象 package com.basics; import com.alibaba.fastjson.JSONObject; import java.util.List; import ...
- 【DSP开发】【Linux开发】基于ARM+DSP进行应用开发
针对当前应用的复杂性,SOC芯片更好能能满足应用和媒体的需求,集成众多接口,用ARM做为应用处理器进行多样化的应用开发和用户界面和接口,利用DSP进行算法加速,特别是媒体的编解码算法加速,既能够保持算 ...
- BCD与ASCII码互转-C语言实现
/*BCD 与 ASCII码转换*/ /******************************************************************* 函数名: asc2bc ...
- springboot + mybaits + oracle 项目
1.pom设置 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...
- 关于golang select的用法
1 go的信道 1.1 什么是信道 信道可以理解为go协程之间进行通信的通道. 1.2 信道的声明 所有的信道都关联一个类型,一旦关联了类型,该信道就只能传输该类型的数据,传输其它类型的数据的话就是非 ...
- GraphQL入门有这一篇就足够了
GraphQL入门有这一篇就足够了:https://blog.csdn.net/qq_41882147/article/details/82966783 版权声明:本文为博主原创文章,遵循 CC 4. ...