内容概览
- flask展示用户信息案例
- 配置文件写法
- 路由系统
- 路由本质
- cbv写法
- 模板语法
flask展示用户信息案例
from flask import Flask, request, render_template, session, redirect
app = Flask(__name__)
app.secret_key = 'asdfasfd35435634**&#)#)$)$%$'
USERS = {
1: {'name': '张三', 'age': 18, 'gender': '男', 'text': "道路千万条"},
2: {'name': '李四', 'age': 28, 'gender': '男', 'text': "安全第一条"},
3: {'name': '王五', 'age': 18, 'gender': '女', 'text': "行车不规范"},
}
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
else:
username = request.form.get('username')
password = request.form.get('password')
if username == 'xxx' and password == '123':
session['is_login'] = True
return redirect('/index')
else:
return render_template('login.html', errors='用户名或密码错误')
@app.route('/index')
def index():
if session.get('is_login'):
return render_template('index.html', users=USERS)
else:
return redirect('/login')
@app.route('/detail/<int:id>')
def detail(id):
if session.get('is_login'):
user = USERS.get(id)
return render_template('detail.html', user=user)
else:
return redirect('/login')
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8000)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form method="post">
<p>用户名:<input type="text" name="username"></p>
<p>密码:<input type="password" name="password"></p>
<input type="submit" value="提交"> <span>{{ errors }}</span>
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>用户信息--模板语言</h1>
<table>
{% for k,v in users.items() %}
<tr>
<td>{{ k }}</td>
<td>{{ v.name }}</td>
<td>{{ v['name'] }}</td>
<td>{{ v.get('name') }}</td>
<td><a href="/detail/{{ k }}">查看详细</a></td>
</tr>
{% endfor %}
</table>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>用户名字:{{ user.name }}</h2>
<h2>用户年龄:{{ user.age }}</h2>
<h2>用户性别:{{ user.gender }}</h2>
<h2>用户介绍:{{ user.text }}</h2>
</body>
</html>
配置文件写法
"""1 使用配置文件之一:(写小脚本测试阶段用)直接通过app对象,配置上,只能配置几个,本质都要放到app.config中"""
app.debug=True
app.secret_key='asdfasf4555'
app.session_cookie_name='sss'
print(app.config)
"""2 直接通过app.config 配置"""
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = 'asfasdf'
print(app.config)
"""3 通过配置文件(很像djagno),不常用"""
DEBUG=True
SECRET_KEY='aaaaa'
app.config.from_pyfile('settings.py')
print(app.config)
"""4 通过类配置(用的多,可以有多套配置)"""
class Config(object):
DEBUG = False
TESTING = False
DATABASE_URI = 'sqlite://:memory:'
class ProductionConfig(Config):
DEBUG = False
DATABASE_URI = 'mysql://192.168.11.11/foo'
class DevelopmentConfig(Config):
DEBUG = True
DATABASE_URI = 'mysql://127.0.0.1/foo'
app.config.from_object('setting.DevelopmentConfig')
app.config.from_object('setting.ProductionConfig')
print(app.config)
"""5 以下,做了解"""
app.config.from_envvar("环境变量名称")
app.config.from_json("json文件名称")
import requests
res = request.get('获取配置数据').json()
app.config.from_mapping(res)
路由系统
"""djagno中,路由是单独的urls.py;flask中是装饰的形式"""
@app.route(参数)
重要的参数:
-rule: 字符串的路径,使用转换器 <string:name> <name>
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
-methods: 列表,规定请求的方式,如果列表中没有,该请求方式不被支持
-endpoint:路由别名,如果不写,会以被装饰的函数名作为别名,django中叫name
路由本质
"""
flask中路由是使用装饰器的,但是它的本质其实是app对象(Flask)的方法self.add_url_rule(rule, endpoint, f, **options)
如果在视图函数上加了装饰器,其实本质是在调用self.add_url_rule
-我们可以不加装饰器,自己调用这个方法,也能完成路由的注册
"""
@decorator
def index():
def decorator(f):
endpoint = options.pop("endpoint", None)
self.add_url_rule(rule, endpoint, f, **options)
return f
-rule:就是装饰器传入的路径,路由
-endpoint:别名
-view_func:视图函数不加括号
app.add_url_rule('/home', view_func=home, endpoint='home')
add_url_rule的参数
@app.route和app.add_url_rule参数:
为函数提供参数,就是djagno中得kwargs
strict_slashes = None
'''
@app.route('/index', strict_slashes=False)
#访问http://www.xx.com/index/ 或http://www.xx.com/index均可
@app.route('/index', strict_slashes=True)
#仅访问http://www.xx.com/index
'''
redirect_to = None,
'''
@app.route('/index/<int:nid>', redirect_to='/home/<nid>')
'''
cbv写法
flask的cbv写法
class Login(MethodView):
def get(self):
return '我是get'
def post(self):
return '我是psot'
app.add_url_rule('/login', view_func=Login.as_view(name='index'))
cbv加装饰器
类属性中加入,加入decorators = [auth, ],属性是一个列表,按照列表顺序,依次给每个方法加装饰器
def as_view(cls, name, *class_args, **class_kwargs ) :
....
if cls.decorators:
for decorator in cls.decorators:
'''
# 装饰器原理:
@auth
def view():
本质是 view=auth(view)
'''
view = decorator(view)
return view
as_view的执行流程
def as_view(cls, name, *class_args, **class_kwargs):
def view(**kwargs):
return self.dispatch_request(**kwargs)
return view
-请求来了,路由匹配成功,会执行as_view内的view()----》self.dispatch_request---》MethodView的dispatch_request
-MethodView的dispatch_request
def dispatch_request(self, **kwargs):
meth = getattr(self, request.method.lower(), None)
return meth(**kwargs)
as_view中的name参数
-先研究 endpoint 有什么用,正常的fbv,如果不写endpoint,会以函数名作为别名,endpoint如何设置的
-如果endpoint为None,它把函数名作为了endpoint
if endpoint is None:
endpoint = _endpoint_from_view_func(view_func)
options["endpoint"] = endpoint
-Login.as_view(name='index'),name到底有啥用
-app.add_url_rule('/login', view_func=Login.as_view('login'))
-没有传endpoint,Login.as_view('login')是 view函数的内存地址,
-endpoint会以函数名作为endpoint的值,现在所有函数都是view,必须传入name,来修改调view函数的名字
-如果传了endpoint,别名以endpoint为主,如果不传endpoint,别名以name为主
app.add_url_rule('/login', view_func=Login.as_view(name='login'),endpoint='xxx')
继承view写cbv
-1 继承 View 的视图类,执行流程都是一样的
-2 请求来了,路由匹配成功,执行self.dispatch_request
-3 self.dispatch_request 没有实现,直接抛异常NotImplementedError()
-4 必须重写 dispatch_request,自己写匹配规则,执行不同的方法
cbv中methods作用
-用来控制允许的请求方式
-如果不写,写了什么方法,就允许什么请求
模板语法
"""dtl中得所有语法,它都支持,并且能够使用 函数() 可以传参数"""
from flask import Flask, render_template,Markup
app = Flask(__name__)
@app.route('/')
def index():
a='<a href="http://www.baidu.com">点我</a>'
return render_template('test.html',a=a)
if __name__ == '__main__':
app.run()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{#{{ name }}---{{ age }}#}
{#<table>#}
{# {% for k,v in user.items() %}#}
{# <tr>#}
{# <td>{{ k }}</td>#}
{# <td>{{ v.name }}</td>#}
{# <td>{{ v['name'] }}</td>#}
{# <td>{{ v.get('name') }}</td>#}
{# <td><a href="/detail/{{ k }}">查看详细</a></td>#}
{# </tr>#}
{# {% endfor %}#}
{#</table>#}
{#<table>#}
{# {% if name %}#}
{# <h1>Hello {{ name }}!</h1>#}
{# {% else %}#}
{# <h1>Hello World!</h1>#}
{# {% endif %}#}
{#</table>#}
{#{{ a|safe }}#}
{{ a}}
</body>
</html>