flask
配置文件config.py
UEDITOR_UPLOAD_PATH = os.path.join(os.path.dirname(__file__), 'postpics')
DEBUG = True
SQLALCHEMY_DATABASE_URI = "mysql://root:123456@127.0.0.1:3306/SOT"
SQLALCHEMY_TRACK_MODIFICATIONS = False
PERMANENT_SESSION_LIFETIME = timedelta(days=7)
SECRET_KEY = "jason flask"
配置文件导入
# 类的形式导入
app.config.from_object(config)
中间模板exts.py
保存db和email对象,在main中进行初始化mail.init_app(app),db.init_app(app)。防止循环引用。
from flask_sqlalchemy import SQLAlchemy
from flask_mail import Mail
db = SQLAlchemy()
mail = Mail()
接收前段传来的值
request.form.get('name') # post的值
request.json.get('name') # post获取值
request.args.get('city') # get传来的值,或获取url中的参数
request.data # Data属性用来获取请求体中的内容
fileObj=request.file.get(“filename”) # File类型上传
fileObe.save(“保存路径”) # 保存到本地
蓝图
在各个模块中init.py中生成蓝图,view中引用,app中注册。
main.py:
app = Flask(__name__)
app.config.from_object(config)
app.register_blueprint(app_cms, url_prefix="/cms")
db.init_app(app)
init.py:
from flask import Blueprint
app_cms = Blueprint("app_cms", __name__)
from .views import LoginView
from .hooks import before_request
自定义转换器
from wekzeug.routing import BaseConverter
class regexconver(BaseConverter):
def __init__(self, url_map, regex):
super().__init__(url_map)
self.regex = regex
app.url_map.converters["re"] = regexconver # 添加自定义转换器到默认转换器字典中
@app.route('/index/<re(r"1[34589]\d{9}"):mobile>') # 使用!!!
def hello_world(mobile):
return 'Hello World! %s' % mobile
钩子函数
@cotent.process 上下文处理,用于向模板传递后台信息。模板都可以用。
@app.before_first_request 第一次请求之前被执行
@app.before_request g对象保存用户信息
@app.after_request 每次视图结束都会执行
@app.teardown_request 可以用于判断每次请求,再进行相对的逻辑处理。
@app.before_first_request
def handle_before_first():
"""第一次请求之前被执行"""
print("handle_before_first")
@app.before_request
def before_every():
"""每次请求之前都会被执行"""
print("before_request")
@app.after_request
def after_every(resp):
"""视图未出现异常,每次视图结束都会执行"""
print("after_request")
return resp
@app.teardown_request
def teard(resp):
"""无论有没有异常,每次视图结束都会执行"""
print("teardown_request")
return resp
模板渲染
data={'name':'jason','age'=30 }
Render_template('index.html', name='jason') Render_template('index.html', **data)
flask过滤器:{{ url01 | upper | reverse | reverse | lower }}
过滤器:{{ 'jason' | trim }} # 转译应对xss攻击:
WTF自定义表单
class ResetEmailForm(BaseForm):
email = StringField(validators=[Email('请输入正确邮箱格式'), InputRequired('请输入邮箱')])
code = StringField(validators=[DataRequired('验证码为空'),
Length(min=6, max=6, message='验证码只能为六位')])
# validate_email后面必须是email才能验证email,filed是上面传下来的email参数。
def validate_email(self, filed):
email = filed.data
if email == g.cms_user.email:
raise ValidationError('该邮箱为原邮箱')
view里面使用WTF验证:
class ResetEmail(views.MethodView):
decorators = [login_required]
def post(self): # 如果是post请求,就会将前端发送的数据在构造函数时存入form对象中。
form = ResetEmailForm(request.form)
if form.validate(): # 如果提交验证都通过,就为True
user = g.cms_user
user.email = form.email.data # 获取post传入值
db.session.commit()
return BackInfo.success()
else:
return BackInfo.paraerror(message=form.get_error())
app_cms.add_url_rule('/resetemail', view_func=ResetEmail.as_view('resetemail'))
数据库操作
通过设置__ repr __方法进行显示。
一对一
# Role表
class Role(db.Model):
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(80))
role_type_id = db.Column(db.Integer,db.ForeignKey('role_type.id'))
# RoleType表
class Role_type(db.Model):
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(120))
role = db.relationship('Role',backref='role_type',lazy='dynamic')
一对多
class Board(db.Model):
__tablename__ = 'board'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(30), nullable=False)
descrip = db.Column(db.String(240))
class Post(db.Model):
__tablename__ = 'post'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(200), nullable=False)
content = db.Column(db.Text, nullable=False)
boardid = db.Column(db.Integer, db.ForeignKey('board.id'))
board = db.relationship('Board', backref='posts') # 反向回来的引用
多对多
# 中间表
article_tag = db.Table('article_tag',db.Column('article_id',db.Integer,
db.ForeignKey('article.id'),primary_key=True), db.Column('tag_id',
db.Integer,db.ForeignKey('tag.id'), primary_key=True))
# 第一article表
class Article(db.Model):
__tablename__ = 'article'
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
title = db.Column(db.String(100),nullable=False)
#两张表进行关联
tags = db.relationship('Tag',secondary=article_tag,backref = db.backref('articles'))
#第二标签表
class Tag(db.Model):
__tablename__ = 'tag'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(100), nullable=False)
数据库迁移manage .py
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
manager = Manager(app)
Migrate(app, db)
manager.add_command("db", MigrateCommand)
python app.py db init
python app.py db migrate -m “create db” #声明版本是什么操作
python app.py db upgrade
查询历史操作:python app.py db history
数据库版本回退:python app.py db downgrade 加上状态码
通过命令行添加操作
@manager.option("-u", "--username", dest="user_name")
@manager.option("-p", "--password", dest="password")
@manager.option("-e", "--email", dest="email")
def create_cmsuser(user_name, password, email):
user = CMSUser(user_name=user_name, password=password, email=email)
db.session.add(user)
db.session.commit()
print("add user success")
通过命令行执行写的命令语句
@manager.command
def create_role():
vistor = CMSRole(name='访问者', desc='只能访问相关信息')
vistor.permission = CMSPermissions.VISITOR
operator = CMSRole(name='运营人员', desc='管理帖子,评论,前台用户')
operator.permission = CMSPermissions.COMMENTER | CMSPermissions.FRONTUSER | \
CMSPermissions.VISITOR
db.session.add_all([vistor, operator])
db.session.commit()
自定义错误页面
@app.errorhandler(404)
def err_404(err):
return "404 错误 %s" % err
对于flask本身的404与自定义的abort(404)都能够通过自定义标准错误页面展示。
自定义响应信息
flask import make_response
resp = make_response("jason is comming") # 里面的内容就是返回的内容
resp.status = "666 666status"
resp.headers = {"name": "zj", "age": 30}
resp.set_cookie('uname','jason') # 可以通过request.cookies.get('uname')来获取内容
Session
Flask将session保存在客户端的cookie中,通过秘钥加密。必要SECRET_KEY。
Session跨服务器:调整nginx的转发策略。
app.config["SECRET_KEY"] = "jason"
session["name"] = "python" # 设置session
session.get("name") # 使用session
Cookie
通过response创建cookie,request获取,删除的本质就是设置cookie时间。创建cookie实质就是修改了response的响应头信息。
resp = make_response()
resp.set_cookie
("alx_cookie", "u_id", max_age=3600)