# 1. 导入Flask类
from flask import Flask
# 2.创建Flask类,输入参数__name__表示指定当前Flask框架所处的路径,以便获取模版目录和静态文件的目录
app = Flask(__name__)
# 实现主页
@app.route('/')
def index():
return "这是网站的主页"
# 设置基本路由 /login/---访问路径
@app.route('/login/')
# 视图函数 告诉app当用户访问/login/这个路径时, 执行login函数的内容, 最终将return的内容返回给客户端;
def login():
return 'login......
'
if __name__ == '__main__':
# 运行Flask应用
# 127.0.0.1----回环地址IP, 每台主机都有====localhost
# 如何设置, 使得服务奇特主机的浏览器可以访问? '0.0.0.0'开放所有的IP, 使得可以访问
# 如何修改端口? # 可能会报错:Address already in use
app.run(host='0.0.0.0',port=8080)
在访问豆瓣电影网站时,我们会发现url有一定的规律
格式为 http://www.douban.org/xxxxx/comments/
如下:
在Flask中有动态路由,格式为:http://www.douban.org/<>/comments/
# request叫做请求上下文
from flask import Flask, request
app = Flask(__name__)
@app.route("//comments/")
def comments(id):
return "这是一个%s评论页面" %(id)
# 字符串
@app.route("/welcome//")
def welcome(username):
return "欢迎用户%s登陆网站
" %(username)
# 以百度搜索引擎为例:http://www.baidu.com/query?id=123&name=westos
from flask import Flask, request
app = Flask(__name__)
@app.route('/query')
def query():
# 获取客户端的用户代理;
user_agent = request.user_agent
# 获取客户端的IP地址;
req_addr = request.remote_addr
# 获取用户请求url地址里面key值对应的value值;
id = request.args.get('id')
name = request.args.get('name')
# 查看客户端的HTTP请求方式;
reqMethod = request.method
# 将字符串信息返回给客户端浏览器/其他, 默认以html方式显示, 如果需要换行, 加html的标签
;
return """
请求的用户代理: %s
请求的客户端Ip: %s
请求的id号: %s
用户名: %s
请求方式: %s
""" %(user_agent, req_addr, id, name, reqMethod)
if __name__ == '__main__':
app.run(host='0.0.0.0',port=8080)
GET:
1). 获取页面信息;
2). 可以提交数据信息;但是数据不安全;会显示用户的密码。
http://127.0.0.1:5000/login2/?username=westos&password=westos
POST:
提交服务端需要的请求信息;url不会显示用户的相关信息;有利于数据的安全性;
PUT:
用户端向服务器往指定url上上传资源
DELETE:
用户端往服务器上删除指定url上的资源
常用的请求方法为GET、POST方法
from flask import Flask, render_template, request, redirect
app = Flask(__name__)
@app.route('/')
def index():
return "主页
"
@app.route('/login/')
def login():
# 一般情况, 不会直接把html文件内容直接返回;
# 而是将html文件保存到当前的templates目录中;
# 1). 通过render_template方法调用;
# 2). 默认情况下,Flask 在程序文件夹中的 templates 子文件夹中寻找模板。
return render_template('login.html')
@app.route('/login2/')
def login2():
# 获取用户输入的用户名
username = request.args.get('username', None)
password = request.args.get('password', None)
# 逻辑处理, 用来判断用户和密码是否正确;
if username == 'root' and password == 'redhat':
# 重定向到指定路由;
return redirect('/')
# return "登录成功"
else:
return "登录失败"
if __name__ == '__main__':
app.run()
Title
用户登录
from flask import Flask, request, render_template, redirect
app = Flask(__name__)
@app.route('/')
def index():
return "这是主页"
# 默认路由只支持get方法, 如何指定接受post方法?
@app.route('/login/', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
# 难点: post请求提交的数据如何获取?
print(request.form)
username = request.form.get('username', None)
password = request.form.get('password', None)
# 如果用户名和密码正确, 跳转到主页;
if username == 'root' and password == 'redhat':
return redirect('/')
# 如果登录不正确, 则警告红色信息;还是在登录页面;
else:
# 可以给html传递变量
# errMessages(根据用户自己定义)表示的html中的变量名
return render_template('login_post.html',
errMessages="用户名或者密码错误"
)
else:
return render_template('login_post.html')
# 在应用对象中有错误处理的装饰器.errorhandler
@app.errorhandler(404)
# 定义页面错误处理的视图函数时,需要传递参数e
def page_not_found(e):
#
return render_template("404.html"), 404
@app.errorhandler(500)
def internal_server_error(e):
return render_template("500.html"), 500
if __name__ == '__main__':
app.run()
Title
用户登录
Title
404
Title
服务器正忙, 请稍后再试
完整的过滤器查看位置: http://jinja.pocoo.org/docs/templates/#builtin-filters
Jinja2变量内置过滤器:
自定义过滤器:
from flask import Flask, render_template
app = Flask(__name__)
class User(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "" %(self.name)
@app.route('/')
def index():
message = " this is a Message "
li = ['fentiao', 'fensi', 'fendai']
info = {
'name': 'fentiao',
'age':10
}
fentiao = User(name="粉条", age=5)
tags = "hello world
"
return render_template('index.html',
message=message,
names = li,
info=info,
fentiao=fentiao,
tags = tags
)
def format_data(s):
return "这是一个过滤器:" + s
app.add_template_filter(format_data, 'fmt')
Title
{{ message | fmt}}
{{ message | lower}}
{{ message | upper}}
{{ message | title}}
{{ message | capitalize}}
{{ names }}
{{ info }}
{{ fentiao }}
{{ tags | striptags }}
{{ tags | safe }}
{% for i in li%}
{% endfor %}
{% if user == ‘westos’%}
{% elif user == ‘hello’ %}
{% else %}
{% endif%}
{% macro render(id) %}
hello world {{ id }}
{% endmacro %}
{{ render(1) }}
{{ render(2) }}
{{ render(3) }}
一般网站的导航栏和底部不会变化, 为了避免重复编写导航栏信息;
{% block title %}
{% endblock %}
{% block title %} {% endblock %}
这是导航栏
{% block body %}
hello
{% endblock %}
这是底部
{% extends '06_base.html'%}
{% block title %}
继承案例
{% endblock %}
{% block body %}
这是最新填的block内容
{% endblock %}
Bootstrap是美国Twitter公司的设计师Mark Otto和Jacob Thornton合作基于HTML、CSS、JavaScript 开发的简洁、直观、强悍的前端开发框架,使得 Web 开发更加快捷。Bootstrap提供了优雅的HTML和CSS规范,它即是由动态CSS语言Less写成。
在导入前,需要将下载好的bootstrap压缩包内的js、css、font目录移动到static目录下
除了导入下载好的本地静态文件,还可以根据官方中文文档导入url地址
# 两种方法: 任选一种
#通过路径导入
-
# 通过url_for函数导入,
-
两种方法:
- 注册
- 登录
# 根据视图函数动态的去查找路径;
- 删除 === /delete/root/
1). flash消息这种功能,是Flask的核心特性。用于在下一个响应中显示一个消息,让用户知道状态发生了变化。可以使确认消息,警告或者错误提醒。
2). 工作原理:
闪现系统使得在一个请求结束的时候记录一个信息,然后在且仅仅在下一个请求中访问这个数据。
仅调用flash()函数并不能把消息显示出来,程序使用的模板要渲染这些消息。Flask把get_flashed_messages()函数开放给模板,用来获取并渲染消息
{#让每个页面都可以获取闪现信息闪现,需要将这条代码放在基模板中#}
{% for item in get_flashed_messages() %}
{{ item }}
{% endfor %}
Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。
def is_login(f):
"""用来判断用户是否登录成功"""
@wraps(f)
def wrapper(*args, **kwargs):
# 判断session对象中是否有seesion['user'],
# 如果包含信息, 则登录成功, 可以访问主页;
# 如果不包含信息, 则未登录成功, 跳转到登录界面;;
if session.get('user', None):
return f(*args, **kwargs)
else:
flash("用户必须登录才能访问%s" % (f.__name__))
return redirect(url_for('login'))
return wrapper
def is_admin(f):
"""用来判断用户是否登录成功"""
@wraps(f)
def wrapper(*args, **kwargs):
# 判断session对象中是否有seesion['user']等于root,
# 如果包含信息, 则登录成功, 可以访问主页;
# 如果不包含信息, 则未登录成功, 跳转到登录界面;;
if session.get('user', None) == 'root':
return f(*args, **kwargs)
else:
flash("只有管理员root才能访问%s" % (f.__name__))
return redirect(url_for('login'))
return wrapper
import os
# url_for函数通过视图函数查找并返回对应的路由
from flask import Flask, render_template, request, redirect, url_for, flash, session
from functools import wraps
users = [
{
'username': 'root',
'password': 'root'
},
{
'username': 'hello',
'password': 'root'
},
]
# 实现用户注册, 用户登录, 用户注销, 用户查看;
app = Flask(__name__)
# 在服务器存储flash数据时,会将flash数据加上这个密钥值进行加密
# 密钥值越长,安全性越高
app.config['SECRET_KEY'] = 'westos'
# flash可以保存多个信息
def is_login(f):
"""用来判断用户是否登录成功"""
# 装饰wrapper将函数名改回原本的函数名f
@wraps(f)
def wrapper(*args, **kwargs):
# 判断session对象中是否有seesion['user'],
# 如果包含信息, 则登录成功, 可以访问主页;
# 如果不包含信息, 则未登录成功, 跳转到登录界面;;
if session.get('user', None):
return f(*args, **kwargs)
else:
flash("用户必须登录才能访问%s" % (f.__name__))
return redirect(url_for('login'))
return wrapper
def is_admin(f):
"""用来判断用户是否为root用户"""
# 装饰wrapper将函数名改回原本的函数名f
@wraps(f)
def wrapper(*args, **kwargs):
# 判断session对象中是否有seesion['user']等于root,
# 如果包含信息, 则登录成功, 可以访问主页;
# 如果不包含信息, 则未登录成功, 跳转到登录界面;;
if session.get('user', None) == 'root':
return f(*args, **kwargs)
else:
flash("只有管理员root才能访问%s" % (f.__name__))
return redirect(url_for('login'))
return wrapper
# 主页
# 必须是is_login装饰器在下,app.route('/')装饰器在上
# 根据多个装饰器的调用过程,装饰器从下往上调用
# 但装饰器里面的wrapper函数是从上往下执行
# 所以首先根据路由找到视图函数,再根据is_login判断用户是否登录
@app.route('/')
@is_login
def index():
return render_template('index.html')
# 用户注册
@app.route('/register/', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
username = request.form.get("username", None)
password = request.form.get('password', None)
# 当所有的信息遍历结束, 都没有发现注册的用户存在, 则将注册的用户添加到服务器, 并跳转登录界面;
for user in users:
if user['username'] == username:
return render_template('register.html', message="用户%s已经存在" % (username))
else:
users.append(dict(username=username, password=password))
# return redirect('/login/')
# 出现一个闪现信息;
flash("用户%s已经注册成功, 请登录....." % (username), category='info')
return redirect(url_for('login'))
return render_template('register.html')
# 用户登录
@app.route('/login/', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get("username", None)
password = request.form.get('password', None)
# 当所有的信息遍历结束, 都没有发的用户存在, 则将注册的用户添加到服务器, 并跳转登录界面;
for user in users:
if user['username'] == username and user['password'] == password:
# 将用户登录的信息存储到session中;
session['user'] = username
return redirect(url_for('index'))
else:
# 出现一个闪现信息;
flash("用户%s密码错误, 请重新登录....." % (username))
return redirect(url_for('login'))
return render_template('login.html')
# 注销用户
@app.route('/logout/')
def logout():
# 将用户存储到session中的信息删除;
session.pop('user')
flash("注销成功........")
return redirect(url_for('login'))
# 删除用户信息
@app.route('/delete//')
def delete(username):
for user in users:
# 用户存在, 则删除;
if username == user['username']:
users.remove(user)
flash("删除用户%s成功" % (username))
else:
flash("用户%s不存在" % (username))
# 删除成功, 跳转到/list/路由中.....
return redirect(url_for('list'))
# 列出用户信息
@app.route('/list/')
@is_login
@is_admin
def list():
return render_template('list.html',
users=users)
# 上传图片
@app.route('/upload/', methods=['POST', 'GET'])
def upload():
if request.method == 'POST':
# 获取用户上传的文件对象
f = request.files['faceImg']
# 获取上传文件的文件名
# print(f.filename)
# 获取当前项目的目录位置;
basepath = os.path.dirname(__file__)
# print(__file__) # /root/PycharmProjects/day34/app.py
# print(basepath) # /root/PycharmProjects/day34
# /root/PycharmProjects/day34/static/img/face/xxx.png
# 拼接路径, 保存到本地的位置;
filepath = os.path.join(basepath, 'static', 'img', 'face', f.filename)
# 保存文件
f.save(filepath)
flash("上传文件%s成功" %(f.filename))
return redirect(url_for('upload'))
else:
return render_template('upload.html')
if __name__ == '__main__':
app.run()
Myhtml-{% block title %} {% endblock %}
{#让每个页面都可以获取闪现信息闪现#}
{% for item in get_flashed_messages() %}
{{ item }}
{% endfor %}
{#中间的部分需要修改#}
{% block content %}
{% endblock %}
{##}
{% extends 'base.html' %}
{% block title %} 主页 {% endblock %}
{% block content %}
这是主页
{% endblock %}
{% extends 'base.html' %}
{% block title %} 用户显示{% endblock %}
{% block content %}
{% endblock %}
{% extends 'base.html' %}
{% block title %} 登录页面{% endblock %}
{% block content %}
{% endblock %}
register.html:
{% extends 'base.html' %}
{% block title %} 注册页面{% endblock %}
{% block content %}
注册
已有帐号
{# 登录#}
登录
{# action : 将表单填写的数据提交到那个URL里面进行处理, #}
{# url_for('register') : 根据视图函数寻找对应的url地址,/register/ #}
{# method =['post', 'get'] , 这种是错误的, 提交数据只能选择一种HTTP请求方法; #}
{% if message %}
{{ message }}
{% endif %}
{% endblock %}
upload.html:
{% extends 'base.html' %}
{% block title %} 上传文件 {% endblock %}
{% block content %}
上传头像
{# enctype="multipart/form-data"用于接收特殊的数据, 包括视频, 图片, 音乐.....,
默认只能接收text/plain #}
{% endblock %}