四件套的使用
案例一 实现登录功能
1 新手四件套
-返回字符串 return ‘字符串’
-返回模板 return render_template(‘模板名字’,参数=值,参数=值)–》参数可以在模板中使用
-返回重定向 return redirect(‘/index’)
-返回json格式 return jsonify(字典/列表)
2 session的使用
全局导入,直接使用,必须指定app.secret_key
设置值:session[‘key’]=value
取值:session.get(‘key’)
咱么写入到session后---》会以cookie形式放到浏览器中
之前django存到session中的数据--》存到django-session表中了
flask 放到session中的数据--》加密后,放到cookie中了
# request(全局有效,但是执行函数的时候会自动区分请求), render_template(返回html页面) redirect(重定向), session(全局有效)
from flask import Flask, request, render_template, redirect, session
# 登录显示用户信息小案例
app = Flask(__name__)
app.secret_key = 'asfasdf.asdf3932.asf3afasdfllg'
app.debug = True
# 常量--》写死用户信息
USERS = {
1: {'name': '刘亦菲', 'age': 18, 'gender': '男', 'text': "刘亦菲,1987年8月25日出生于湖北省武汉市,华语影视女演员、歌手,毕业于北京电影学院2002级表演系本科",
'img': 'https://img2.woyaogexing.com/2021/10/16/e3ccba623848430ba83209c0621a2256!400x400.jpeg'},
2: {'name': '彭于晏', 'age': 28, 'gender': '男', 'text': "彭于晏,1982年3月24日出生于中国台湾省澎湖县,毕业于不列颠哥伦比亚大学,华语影视男演员。。。。。。。。",
'img': 'https://img2.woyaogexing.com/2021/10/16/e71aa35728c34313bccb4c371192990f!400x400.jpeg'},
3: {'name': '迪丽热巴', 'age': 38, 'gender': '女', 'text': "迪丽热巴(Dilraba),1992年6月3日出生于中国新疆乌鲁木齐市,毕业于上海戏剧学院,中国内地影视女演员",
'img': 'https://img2.woyaogexing.com/2021/10/30/6a34146dde2d4f1c832463a5be1ed027!400x400.jpeg'},
4: {'name': '亚瑟', 'age': 38, 'gender': '男', 'text': "亚瑟,是腾讯手游《王者荣耀》中一名战士型英雄角色,也是《王者荣耀》的新手英雄之一,既可攻又可守",
'img': 'https://img2.woyaogexing.com/2021/10/30/371b2aa7a03c4f53b7b1bc86f877d7d1!400x400.jpeg'},
}
@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 == 'lqz' and password == '123':
# 把登录信息写入到session中,一旦用session,必须指定 秘钥
session['name'] = username
# 重定向
# return redirect('http://www.baidu.com')
return redirect('/')
else:
# 返回模板,把错误信息渲染到模板
return render_template('login.html', error='用户名或密码错误')
# 必须登录后,才能访问首页和详情页,如果没登录---》重定向到登录页面
@app.route('/')
def index():
if session.get('name'):
return render_template('index.html', users=USERS)
else:
return redirect('/login')
@app.route('/detail/<int:id>')
def detail(id):
if session.get('name'):
user = USERS.get(id)
return render_template('detail.html', info=user)
else:
return redirect('/login')
if __name__ == '__main__':
app.run()
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css">
<title>登录</title>
</head>
<body>
<div class="container col-xl-10 col-xxl-8 px-4 py-5">
<div class="row align-items-center g-lg-5 py-5">
<div class="col-lg-7 text-center text-lg-start">
<h1 class="display-4 fw-bold lh-1 mb-3">亚洲最大交友平台</h1>
<p class="col-lg-10 fs-4">Bootstrap是Twitter推出的一个用于前端开发的开源工具包。它由Twitter的设计师Mark
Otto和Jacob Thornton合作开发,是一个CSS/HTML框架。目前,Bootstrap最新版本为5.0</p>
</div>
<div class="col-md-10 mx-auto col-lg-5">
<form class="p-4 p-md-5 border rounded-3 bg-light" method="post">
<div class="form-floating mb-3">
<input type="text" class="form-control" id="floatingInput" placeholder="name@example.com" name="username">
<label for="floatingInput">用户名</label>
</div>
<div class="form-floating mb-3">
<input type="password" class="form-control" id="floatingPassword" placeholder="Password" name="password">
<label for="floatingPassword">密码</label>
</div>
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> 记住密码
</label>
</div>
<button class="w-100 btn btn-lg btn-primary" type="submit">登录</button>
<hr class="my-4">
<small class="text-muted">{{error}}</small>
</form>
</div>
</div>
</div>
</body>
</html>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
<title>Title</title>
</head>
<body>
<div class="container">
<!-- 头部-->
<div class="sticky-top">
<header class="d-flex flex-wrap justify-content-center py-3 mb-4 border-bottom">
<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none">
<svg class="bi me-2" width="40" height="32">
<use xlink:href="#bootstrap"></use>
</svg>
<span class="fs-4">交友平台</span>
</a>
<ul class="nav nav-pills">
<li class="nav-item"><a href="#" class="nav-link active" aria-current="page">首页</a></li>
<li class="nav-item"><a href="#" class="nav-link">女生</a></li>
<li class="nav-item"><a href="#" class="nav-link">男生</a></li>
<li class="nav-item"><a href="#" class="nav-link">国产</a></li>
<li class="nav-item"><a href="#" class="nav-link">欧美</a></li>
</ul>
</header>
</div>
<!--轮播图-->
<div>
<div class="bd-example-snippet bd-code-snippet">
<div class="bd-example">
<div id="carouselExampleCaptions" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-indicators">
<button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="0" class=""
aria-label="Slide 1"></button>
<button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="1"
aria-label="Slide 2" class="active" aria-current="true"></button>
<button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="2"
aria-label="Slide 3" class=""></button>
</div>
<div class="carousel-inner">
<div class="carousel-item">
<img src="https://img.zcool.cn/community/01fb5458fedf57a801214550f9677a.jpg@2o.jpg" alt=""
width="100%" height="300">
<div class="carousel-caption d-none d-md-block">
<h5>激情绿荫</h5>
<p>Some representative placeholder content for the first slide.</p>
</div>
</div>
<div class="carousel-item active">
<img src="https://img2.baidu.com/it/u=2951612437,4135887500&fm=253&fmt=auto&app=138&f=JPEG"
alt="" width="100%" height="300">
<div class="carousel-caption d-none d-md-block">
<h5>品牌雨伞</h5>
<p>Some representative placeholder content for the second slide.</p>
</div>
</div>
<div class="carousel-item">
<img src="https://img1.baidu.com/it/u=1417689082,3333220267&fm=253&fmt=auto&app=138&f=JPEG"
alt="" width="100%" height="300">
<div class="carousel-caption d-none d-md-block">
<h5>家装节</h5>
<p>Some representative placeholder content for the third slide.</p>
</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleCaptions"
data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleCaptions"
data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
</div>
</div>
</div>
<!-- 内容-->
<div class="row row-cols-md-2" style="padding: 10px">
{% for k,v in users.items() %}
<div class="card">
<div class="row " style="padding: 10px">
<img src="{{v.get('img')}}" alt="" class="col-md-4">
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title">{{v['name']}}</h5>
<p class="card-text">{{v.text}}</p>
<p class="card-text">
<a href="/detail/{{k}}" class="btn btn-danger">查看详细</a>
</p>
</div>
</div>
</div>
</div>
{%endfor%}
</div>
<!-- table-->
<div class="bd-example" style="margin-top: 30px">
<table class="table table-hover table-striped table-bordered">
<thead>
<tr class="table-danger">
<th colspan="3" class="text-center">更多交友</th>
</tr>
</thead>
<tbody>
<tr class="table-success">
<th>杨幂</th>
<td>女</td>
<td>33</td>
</tr>
<tr class="table-warning">
<th scope="row">刘亦菲</th>
<td>未知</td>
<td>40</td>
</tr>
<tr class="table-success">
<th scope="row">彭于晏</th>
<td>男</td>
<td>23</td>
</tr>
<tr class="table-warning">
<th scope="row">陈奕迅</th>
<td>男</td>
<td>44</td>
</tr>
<tr class="table-success">
<th scope="row">薛之谦</th>
<td>男</td>
<td>36</td>
</tr>
<tr class="table-warning">
<th>李清照</th>
<td>女</td>
<td>未知</td>
</tr>
</tbody>
</table>
</div>
<!--分页-->
<div class="d-flex justify-content-center">
<ul class="pagination pagination-lg">
<li class="page-item">
<a class="page-link" href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">4</a></li>
<li class="page-item"><a class="page-link" href="#">5</a></li>
<li class="page-item"><a class="page-link" href="#">6</a></li>
<li class="page-item">
<a class="page-link" href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</div>
<!-- 尾部-->
<div>
<footer class="py-3 my-4">
<ul class="nav justify-content-center border-bottom pb-3 mb-3">
<li class="nav-item"><a href="#" class="nav-link px-2 text-muted">首页</a></li>
<li class="nav-item"><a href="#" class="nav-link px-2 text-muted">特性</a></li>
<li class="nav-item"><a href="#" class="nav-link px-2 text-muted">联系我们</a></li>
<li class="nav-item"><a href="#" class="nav-link px-2 text-muted">资料获取</a></li>
<li class="nav-item"><a href="#" class="nav-link px-2 text-muted">关于</a></li>
</ul>
<p class="text-center text-muted">Copyright © 1998 - 2029 liuqingzheng. All Rights Reserved. </p>
</footer>
</div>
</div>
</body>
</html>
detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
<title>Title</title>
</head>
<body>
<div class="container">
<div class="sticky-top">
<header class="d-flex flex-wrap justify-content-center py-3 mb-4 border-bottom">
<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none">
<svg class="bi me-2" width="40" height="32">
<use xlink:href="#bootstrap"></use>
</svg>
<span class="fs-4">交友平台</span>
</a>
<ul class="nav nav-pills">
<li class="nav-item"><a href="#" class="nav-link active" aria-current="page">首页</a></li>
<li class="nav-item"><a href="#" class="nav-link">女生</a></li>
<li class="nav-item"><a href="#" class="nav-link">男生</a></li>
<li class="nav-item"><a href="#" class="nav-link">国产</a></li>
<li class="nav-item"><a href="#" class="nav-link">欧美</a></li>
</ul>
</header>
</div>
<div class="position-relative overflow-hidden p-3 p-md-5 m-md-3 text-center bg-light">
<div class="col-md-5 p-lg-5 mx-auto my-5">
<h1 class="display-4 fw-normal">{{info.name}}</h1>
<img src="{{info.img}}" alt=""
width="300px" height="300px" style="margin: 20px">
<p class="lead fw-normal">{{info.text}}</p>
<a class="btn btn-outline-secondary" href="#">收藏</a>
</div>
<div class="product-device shadow-sm d-none d-md-block"></div>
<div class="product-device product-device-2 shadow-sm d-none d-md-block"></div>
</div>
<div>
<footer class="py-3 my-4">
<ul class="nav justify-content-center border-bottom pb-3 mb-3">
<li class="nav-item"><a href="#" class="nav-link px-2 text-muted">首页</a></li>
<li class="nav-item"><a href="#" class="nav-link px-2 text-muted">特性</a></li>
<li class="nav-item"><a href="#" class="nav-link px-2 text-muted">联系我们</a></li>
<li class="nav-item"><a href="#" class="nav-link px-2 text-muted">资料获取</a></li>
<li class="nav-item"><a href="#" class="nav-link px-2 text-muted">关于</a></li>
</ul>
<p class="text-center text-muted">Copyright © 1998 - 2029 liuqingzheng. All Rights Reserved. </p>
</footer>
</div>
</div>
</body>
</html>
flask配置文件
# 1 方式一:放在app对象上,本质会放在 app.config 里面
app.secret_key = 'asdfsdf'
app.debug = False
# 2 方式二:放在app对象的config参数上
# app.config['DEBUG'] = True
# app.config['HOST'] = '127.0.0.1' # 自己配置
# print(app.config)
# 3 方式三:通过py文件设置 settings.py
# app.config.from_pyfile('./settings.py') # 会加载settings中得大写的配置,都放到 config 中
# print(app.config)
# 4 方式四:了解,使用环境变量----dot-env使用
# app.config.from_envvar("环境变量名称")
# 5 方式五,常用,通过类
# 上线阶段使用的配置文件
# app.config.from_object('settings.ProductionConfig')
# 测试阶段使用的配置文件
app.config.from_object('settings.DevelopmentConfig')
print(app.config)
# 创建一个放类的文件
class Config(object):
DEBUG = False
TESTING = False
SECRET_KEY='123'
DATABASE_URI = '127.0.0.1'
class ProductionConfig(Config):
DEBUG = False
SECRET_KEY = 'asfasfd.ea33435asfasf'
DATABASE_URI = '192.168.1.23'
class DevelopmentConfig(Config):
DEBUG = True
DATABASE_URI = '127.0.0.1'
# 6 其他
# app.config.from_json("json文件名称")
# JSON文件名称,必须是json格式,因为内部会执行json.loads
# app.config.from_mapping({'DEBUG': True})
# 配置的默认文件有哪些?
{
'DEBUG': get_debug_flag(default=False), 是否开启Debug模式
'TESTING': False, 是否开启测试模式
'PROPAGATE_EXCEPTIONS': None,
'PRESERVE_CONTEXT_ON_EXCEPTION': None,
'SECRET_KEY': None, #秘钥
'PERMANENT_SESSION_LIFETIME': timedelta(days=31), #sessio过期时间
'USE_X_SENDFILE': False,
'LOGGER_NAME': None,
'LOGGER_HANDLER_POLICY': 'always',
'SERVER_NAME': None,
'APPLICATION_ROOT': None,
'SESSION_COOKIE_NAME': 'session', # 操作session--》成cookie到浏览器--》key值session
'SESSION_COOKIE_DOMAIN': None,
'SESSION_COOKIE_PATH': None,
'SESSION_COOKIE_HTTPONLY': True,
'SESSION_COOKIE_SECURE': False,
'SESSION_REFRESH_EACH_REQUEST': True,
'MAX_CONTENT_LENGTH': None,
'SEND_FILE_MAX_AGE_DEFAULT': timedelta(hours=12),
'TRAP_BAD_REQUEST_ERRORS': False,
'TRAP_HTTP_EXCEPTIONS': False,
'EXPLAIN_TEMPLATE_LOADING': False,
'PREFERRED_URL_SCHEME': 'http',
'JSON_AS_ASCII': True,
'JSON_SORT_KEYS': True,
'JSONIFY_PRETTYPRINT_REGULAR': True,
'JSONIFY_MIMETYPE': 'application/json',
'TEMPLATES_AUTO_RELOAD': None,
}
flask的路由系统
from flask import Flask, render_template, request, redirect
app = Flask(__name__)
# 1 flask路由系统基于装饰器的 但是它的本质是 add_url_rule
# 2 装饰器的参数及作用
'''
1 rule : 路径
2 methods: 可以允许的请求方式
3 endpoint:路由别名
'''
# 第一种
@app.route('/index', methods=['GET', 'POST'])
def index():
return 'hello'
# 第二种 不加装饰器 自己注册
def login():
return 'hello'
app.add_url_rule('/login', view_func=login, methods=['GET', 'POST'], endpoint='login')
if __name__ == '__main__':
app.run()
# 如果是多个路由
"""
app.add_url_rule('/', 'index', index, methods=['GET'])
app.add_url_rule('/login', 'login', login)
"""
# 路由解析
"""
1 rule, URL规则
2 view_func, 视图函数内存地址
3 defaults = None, 默认值, 当URL中无参数,函数需要参数时,使用defaults = {'k': 'v'}为函数提供参数
@app.route('/',defaults={name:lqz})
def index(name):
pass
4 endpoint = None, 名称,用于反向生成URL,即: url_for('名称')
5 methods = None, 允许的请求方式,如:["GET", "POST"]
6 strict_slashes = None 对URL最后的 / 符号是否严格要求
@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
7 redirect_to = None 重定向到指定地址
@app.route('/index/<int:nid>', redirect_to='/home/<nid>')
"""
路由转换器
from flask import Flask, render_template, request, redirect
app = Flask(__name__)
"""
# 转换的类型
DEFAULT_CONVERTERS = {
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
}
"""
@app.route('/<string:name>')
def index(name):
return 'hello' + str(name)
if __name__ == '__main__':
app.run(debug=True)