文章目录
一、day01项目环境和结构搭建
1.1 新建虚拟环境
E:\VirtualEnv\cmd
virtualenv RushInFlask
cd rushinflask
scripts\activate
pip list
1.2 安装Flask
pip install -i https://mirrors.aliyun.com/pypi/simple flask
pip list
1.3 配置Python解释器
二、后端知识要点
2.1 Flask 文档
https://dormousehole.readthedocs.io/en/latest/
2.2 实例化flask对象
2.2.1 新建独立的配置文件settings.py
2.2.2 实例化flask对象时加载配置文件
import settings
app = Flask(__name__)
app.config.from_object(settings)
2.3 基本路由
2.3.1 常用路由及唯一性
######### 常用路由,建议路由格式为 '/path',即前有后无,这样可以确保路由的唯一性
@app.route('/') # 路由 http://127.0.0.1:5000/
def hello_world(): # 视图
return 'Hello World~~~!!!'
2.3.2 路由底层调用
########## 路由底层调用
def index():
return '通过add_url_rul返回!'
app.add_url_rule('/index/', view_func=index)
2.4 路由规则
2.4.1 字符串路由
data = {'bj': '北京', 'sh': '上海', 'gz': '广州', 'sz': '深圳'}
@app.route('/getcity/<city>/') # city是变量名,默认字符串
def get_city(city):
print(type(city))
return f'进入{data.get(city)}市'
2.4.2 path路径路由
@app.route('/index/<path:p>') # http://127.0.0.1:5001/index/username/page_1
def get_path(p):
print(type(p)) # str
return p # 页面返回 username/page_1
2.4.3 数字(整数int、浮点数float)路由
@app.route('/add/<int:num>') # 变量类型不是字符串需要指定,可以是int,float,path,uuid
def add(num):
result = 10 + num
return f'10+{num}={result}'
2.4.4 多参数路由
# 路由多参数传递
@app.route('/add/<int:num1>/<int:num2>') # 变量类型不是字符串需要指定,可以是int,float,path,uuid
def add1(num1, num2):
result = num1 + num2
return f'{num1}+{num2}={result}'
2.4.5 UUID路由
import uuid
res_uid = uuid.uuid4()
print(res_uid) # af8e20c0-876b-4ab2-83d1-f0851e46ac49
# 指定了UUID类型,后面必须放符合uuid格式的变量,接收到的也是uuid变量
@app.route('/index/<uuid:uid>') # http://127.0.0.1:5001/index/af8e20c0-876b-4ab2-83d1-f0851e46ac49
def get_uuid(uid):
print(type(uid)) # <class 'uuid.UUID'>
return str(uid) # af8e20c0-876b-4ab2-83d1-f0851e46ac49
2.5 返回值:Response对象
2.5.1 返回值-字符串
@app.route('/') # 路由 http://127.0.0.1:5000/
def hello_world(): # 视图
return 'Hello World~~~!!!'
2.5.2 返回值-元组:需要转换为Response对象
from flask import Response
tuple1 = ('12', 'ab', '32')
@app.route('/index1')
def index1():
return Response(tuple1) # 页面显示 12ab32
2.5.3 返回值-Response对象
2.5.4 返回值-渲染模板render_template
########### app与模板的结合,默认使用Jinjia2模板引擎,模板文件夹默认为templates
from flask import render_template
@app.route('/', endpoint='index') # endpoint为路由别名
def index():
return render_template('index.html') # Jinjia2模板引擎转化为字符串格式
2.5.5 返回值-重定向redirect
# 接收页面数据
from flask import redirect
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
# 提取 post 方式提交的数据
username1 = request.form.get('username')
password1 = request.form.get('password')
print(username1, password1)
users.append(request.form.to_dict())
return redirect('index.html')
2.6 request对象
########### request 对象
from flask import request
@app.route('/index2')
def index2():
print(request.headers)
print(request.path)
print(request.base_url)
print(request.url)
print(request.full_path)
return 'request对象'
2.7 url_for反向解析
2.7.1 endpoint为路由指定别名
别名可以与函数名不一致
########### app与模板的结合,默认使用Jinjia2模板引擎,模板文件夹默认为templates
@app.route('/', endpoint='index') # endpoint为路由别名
def index():
return render_template('index.html') # Jinjia2模板引擎转化为字符串格式
2.7.2 url_for反向解析
users = []
# 接收页面数据
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
# 提取 post 方式提交的数据
username1 = request.form.get('username')
password1 = request.form.get('password')
print(username1, password1)
users.append(request.form.to_dict())
return redirect(url_for('index')) # 路由endpoint别名反向解析,然后重定向会有两次响应
if request.method == 'GET':
# 提取 get 方式提交的数据
print(request.args)
return render_template('register.html')
2.8 渲染模板时向前端传递参数
2.8.1 字典列表转化为json字符串
json.dumps(users)
2.8.2 渲染模板时向前端传递参数
@app.route('/show')
def show():
context = {}
context['user'] = json.dumps(users)
msg = '<h1>我不想被转义</h1>'
return render_template('show.html', context=users, msg=msg)
2.9 打印当前项目路由映射表
print(app.url_map) # 路由表
三、前端知识要点
3.1 表单提交路由、模式和变量名
- 表单提交路由:/register
- 表单提交模式:post
- 表单提交变量名:name=“username”
<div>
<!-- action="register"为视图函数的路由 -->
<form action="register" method='post'>
<p><input type="text" name="username" placeholder="请输入用户名"></p>
<p><input type="password" name="password" placeholder="请输入密码"></p>
<p><input type="submit" value="注册"></p>
</form>
</div>
3.2 接收后端传来的变量 {{ msg }}
3.3 循环结构
- loop.index 取序号
- loop.last 判断是否是最后一个,返回布尔值
{% for item in context %}
<tr {% if loop.last %} style="background-color: deeppink;" {% endif %}>
<td>{{loop.index}}</td>
<td>{{item.username}}</td>
<td>{{item.password}}</td>
</tr>
{% endfor %}
3.4 判断结构
{% if loop.last %} style="background-color: deeppink;"
{% else %}
{% endif %}>
3.5 过滤器
3.5.1 列表过滤器
<p>列表过滤器</p>
{{ context|length }}<br>
{{ context|first }}<br>
{{ context|last }}<br>
{{ [1,2,3,4]|sum }}<br>
{{ [2,6,5,10,8]|sort }}<br>
3.5.2 字典过滤器
<p>字典过滤器</p>
items()取字典的所有key和value
<br>
{% for k,v in context.0.items() %}
{{k}}--{{v}}
{% endfor %}
<br>
keys()取字典的所有key
<br>
{% for k in context.0.keys() %}
{{k}}
{% endfor %}
<br>
values()取字典的所有value
<br>
{% for v in context.0.values() %}
{{v}}
{% endfor %}
四、项目完整代码
4.1 项目目录结构
4.2 后端代码
4.2.1 settings.py文件
# 配置文件
ENV = 'development'
DEBUG = True
4.2.2 app.py
# Flask 文档 https://dormousehole.readthedocs.io/en/latest/
from flask import Flask, Response, request, render_template, redirect, url_for
import settings
import json
app = Flask(__name__)
app.config.from_object(settings)
######### 常用路由,建议路由格式为 '/path',即前有后无,这样可以确保路由的唯一性
# @app.route('/') # 路由 http://127.0.0.1:5000/
# def hello_world(): # 视图
# return 'Hello World~~~!!!'
# ########## 路由底层调用
# def index():
# return '通过add_url_rul返回!'
# app.add_url_rule('/index/', view_func=index)
######### 路由变量规则
data = {'bj': '北京', 'sh': '上海', 'gz': '广州', 'sz': '深圳'}
@app.route('/getcity/<city>/') # city是变量名,默认字符串
def get_city(city):
print(type(city))
return f'进入{data.get(city)}市'
@app.route('/add/<int:num>') # 变量类型不是字符串需要指定,可以是int,float,path,uuid
def add(num):
result = 10 + num
return f'10+{num}={result}'
# 路由多参数传递
@app.route('/add/<int:num1>/<int:num2>') # 变量类型不是字符串需要指定,可以是int,float,path,uuid
def add1(num1, num2):
result = num1 + num2
return f'{num1}+{num2}={result}'
@app.route('/index/<path:p>') # http://127.0.0.1:5001/index/username/page_1
def get_path(p):
print(type(p)) # str
return p # 页面返回 username/page_1
import uuid
res_uid = uuid.uuid4()
# print(res_uid) # af8e20c0-876b-4ab2-83d1-f0851e46ac49
# 指定了UUID类型,后面必须放符合uuid格式的变量,接收到的也是uuid变量
@app.route('/index/<uuid:uid>') # http://127.0.0.1:5001/index/af8e20c0-876b-4ab2-83d1-f0851e46ac49
def get_uuid(uid):
print(type(uid)) # <class 'uuid.UUID'>
return str(uid) # af8e20c0-876b-4ab2-83d1-f0851e46ac49
########### Response 对象
tuple1 = ('12', 'ab', '32')
@app.route('/index1')
def index1():
return Response(tuple1) # 页面显示 12ab32
########### request 对象
@app.route('/index2')
def index2():
print(request.headers)
print(request.path)
print(request.base_url)
print(request.url)
print(request.full_path)
return 'request对象'
########### app与模板的结合,默认使用Jinjia2模板引擎,模板文件夹默认为templates
@app.route('/', endpoint='index') # endpoint为路由别名
def index():
return render_template('index.html') # Jinjia2模板引擎转化为字符串格式
users = []
# 接收页面数据
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
# 提取 post 方式提交的数据
username1 = request.form.get('username')
password1 = request.form.get('password')
print(username1, password1)
users.append(request.form.to_dict())
return redirect(url_for('index')) # 路由endpoint别名反向解析,然后重定向会有两次响应
if request.method == 'GET':
# 提取 get 方式提交的数据
print(request.args)
return render_template('register.html')
@app.route('/show')
def show():
context = {}
context['user'] = json.dumps(users)
msg = '<h1>我不想被转义</h1>'
return render_template('show.html', context=users, msg=msg)
if __name__ == '__main__':
print(app.url_map) # 路由表
app.run(port=5001)
4.3 前端代码
4.3.1 index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>首页</title>
</head>
<body>
<a href="/register">注册<br></a>
<a href="">登录<br></a>
<a href="/show">展示用户<br></a>
</body>
</html>
4.3.2 register.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>用户注册</title>
<style type="text/css">
div{
width: 50%;
height: 180px;
border: 2px solid brown;
}
</style>
</head>
<body>
<h1>欢迎注册</h1>
<div>
<!-- action="register"为视图函数的路由 -->
<form action="register" method='post'>
<p><input type="text" name="username" placeholder="请输入用户名"></p>
<p><input type="password" name="password" placeholder="请输入密码"></p>
<p><input type="submit" value="注册"></p>
</form>
</div>
</body>
</html>
4.3.3 show.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>用户展示</title>
</head>
<body>
<h1>用户展示</h1>
<ul>
{% for item in context %}
<li> {{item.username}} {{item.password}} </li>
{% endfor %}
</ul>
<table border="1" cellspacing="0" cellpadding="0">
<tr>
<th>序号</th>
<th>用户名</th>
<th>密码</th>
</tr>
{% for item in context %}
<tr {% if loop.last %} style="background-color: deeppink;" {% endif %}>
<td>{{loop.index}}</td>
<td>{{item.username}}</td>
<td>{{item.password}}</td>
</tr>
{% endfor %}
</table>
<hr >
<p>共有{{context|length}}人</p>
<p>{{ msg|safe }}</p>
<p>{{ '%s is %d years old' | format('lily', 18) }}</p>
<hr >
<p>列表过滤器</p>
{{ context|length }}<br>
{{ context|first }}<br>
{{ context|last }}<br>
{{ [1,2,3,4]|sum }}<br>
{{ [2,6,5,10,8]|sort }}<br>
<hr >
<p>字典过滤器</p>
items()取字典的所有key和value
<br>
{% for k,v in context.0.items() %}
{{k}}--{{v}}
{% endfor %}
<br>
keys()取字典的所有key
<br>
{% for k in context.0.keys() %}
{{k}}
{% endfor %}
<br>
values()取字典的所有value
<br>
{% for v in context.0.values() %}
{{v}}
{% endfor %}
</body>
</html>