Flask目录结构
说明:flask 非常灵活,它没有一个固定的项目目录组织结构,以下内容仅供参考。
结果:如图所示,此目录结构为本人正在使用的结构。
- conf/default.py:存储了Flask的一些配置内容。
- main/__init__.py:存储蓝图的目录。
- ops/__init__.py:定义程序,初始化一些对象。
- model/db.py: 定义数据库中数据表。
- static:存储js、css文件。
- templates:存储HTML静态页面模板。
- run.py:程序入口。
1. conf/default.py注释:
import os
class Config:
# 使用导入的os模块来生成随机秘钥,此秘钥用于Flask中的session。 SECRET_KEY = os.urandom(24)
# 数据库相关定义,将其设为True时,每次请求结束后都会自动提交数据库中的变动(不过我数据库做更改还是写了commit =.=;) SQLALCHEMY_COMMIT_ON_TEARDOWN = True # 将Config类作为参数传递到其他函数中,又希望在实例化Config类之前就能提供下列的功能,所以使用staticmethod. @staticmethod def init_app(app): pass # 继承Config类,下列定义数据库地址,可以定义多个环境(TestingConfig="测试环境",DevelopmentConfig="开发环境"...) class TestingConfig(Config): SQLALCHEMY_DATABASE_URI = 'mysql://test:test@192.168.xx.xx:3306/test?charset=utf8'
# 如果设置成 True (默认情况),Flask-SQLAlchemy将会追踪对象的修改并且发送信号.这需要额外的内存,如果不必要的可以禁用它 SQLALCHEMY_TRACK_MODIFICATIONS = False # 同上 class DevelopmentConfig(Config): SQLALCHEMY_DATABASE_URI = 'mysql://dev:dev@192.168.xx.xx:3306/dev?charset=utf8' SQLALCHEMY_TRACK_MODIFICATIONS = False # 定义字典,方便其他.py文件引用 config = { 'default': DevelopmentConfig, 'testing': TestingConfig }
2.main/__init__.py
from flask import Blueprint, jsonify, request, render_template, session, json from ops import db, and_ from model.db import User # 定义蓝图,指定模板位置及static文件位置,下面有说明 users = Blueprint('user',__name__,template_folder='../templates',static_folder='../static')
# 因为定义了蓝图,所以就要写"@users.xxx". @users.route('/register',methods=['GET','POST']) # 创建用户 def register(): if request.method == 'POST':
# 这里的data中的数据是获取的前端的AJAX里边的数据. data = json.loads(request.form.get('register_data')) if data: user = data['register_user'] passwd = data['register_password'] re_password = data['repeatpassword']
# 前往数据库查询数据 alreay = User.query.filter(User.name == user).first()
'''
下列的return jsonify都是返还给AJAX一个字典,前端AJAX调用结果进行弹窗.
''' if alreay: return jsonify({'code': '300', 'data': '用户已存在!'}) elif passwd != re_password: return jsonify({'code': '100', 'data': '注册密码与确认密码不一致'}) insert = User(name=user,password=passwd,status=0) db.session.add(insert) db.session.commit() return jsonify({'code': '200','data':'用户创建成功!'}) return render_template('register.html')
# 下列内容与上述内容大同小异,不做过多解释 @users.route('/forbidden',methods=['POST']) # 禁用用户 def forbidden(): data = json.loads(request.form.get('data')) web_user = data['user'] forbidden = User.query.filter(and_(User.name == web_user, User.status == '1')).first() if forbidden: if forbidden.status == "1": forbidden.status = 0 db.session.commit() return jsonify({"code": "200", "data": "账户禁用完成!"}) return jsonify({"code": "300", "data": "账户已被禁用!"}) @users.route('/start_using',methods=['POST']) # 激活用户 def start_using(): data = json.loads(request.form.get('data')) web_user = data['user'] start_using = User.query.filter(and_(User.name == web_user, User.status == '0')).first() if start_using: if start_using.status == "0": start_using.status = 1 db.session.commit() return jsonify({"code": "300", "data": "账户启用完成!"}) return jsonify({"code": "300", "data": "账户已被启动!"}) @users.route('/del_user',methods=['POST']) def del_user(): data = json.loads(request.form.get('data')) del_user = data['user'] web_user = session['user'] update_pass = User.query.filter(User.name == del_user).first() if update_pass: if web_user == 'admin': db.session.delete(update_pass) db.session.commit() db.session.execute('alter table user_info AUTO_INCREMENT 1') return jsonify({"code": "200","data":"账户删除成功!"}) return jsonify({'code': '500','data':'你无权删除用户'}) @users.route('/check') # 页面展示数据库中的用户数据 def check(): count = User.query.count() name = User.query.all() return render_template('user_list.html',name=name,count=count)
3.ops/__init__.py
'''
下列很多模块实际在这个文件中并没有用到,导入到这个文件的目的就是防止Python中的循环导入问题.
'''
from flask import Flask,render_template, request, session, redirect, jsonify import os, jsonfrom sqlalchemy import and_ from werkzeug.security import generate_password_hash, check_password_hash from flask_sqlalchemy import SQLAlchemy
# 导入前面定义的Flask的设置. from conf.default import config # 初始化对象,以后续.py引用. db = SQLAlchemy() # 定义个方法,方便引用,接受引用传参; def app_create(config_name):
# 导入users,因为main文件夹下边的__init__.py文件中有users,这个users是蓝图 from main import users
'''
初始化程序,定义模板路径,因为在这里初始化了那么程序就相当于在ops/目录下,但是
默认情况下"templates"路径是和程序同级的,但是这里templates和ops同级,所以
模板路径就要手动定义
一句话就是 模板的位置是相对于程序
static位置同理
''' app = Flask(__name__,template_folder='../templates',static_folder='../static')
# 上面导入了蓝图,这里需要注册蓝图. app.register_blueprint(users)
# 这里调用前面定义的配置文件的对象 app.config.from_object(config[config_name])
# 初始化配置. config[config_name].init_app(app)
# 初始化数据库,官方定义. db.init_app(app)
# 将程序返回,使.py文件可调用全部初始化过的程序. return app
4.model/db.py
# 导入ops中创建的db对象
from ops import db # SQLAlchemy固定语法 class User(db.Model): __tablename__ = 'user_info' id = db.Column(db.Integer, primary_key=True) status = db.Column(db.Integer,nullable=False) name = db.Column(db.String(40),unique=True) password = db.Column(db.String(128),nullable=False) # 自定义输出结果 def __repr__(self): return str('%r') % self.name
5.run.py
# 导入前面创建的"程序创建"方法
from ops import app_create
# 导入模型中的 from model.db import User from ops import render_template, request, session, redirect, jsonify, os, json, generate_password_hash, check_password_hash app = app_create(os.getenv('FLASK_CONFIG') or 'testing') @app.before_request # 判断用户是否登录,是否缓存在session中 def is_login(): if 'user' not in session \ and request.endpoint != 'login' \ and '/static/' not in request.path: return redirect('/login') @app.route('/login',methods=['GET','POST']) # 用户登录 def login(): # 如果以GET请求当前url,直接返回html页面 if request.method == 'GET': return render_template('login.html') ''' 如果以POST请求的话则将前端JS返回的数据与数据库中的数据进行对比,对比成功后返回结果 ''' if request.method == 'POST': data = json.loads(request.form.get('data')) username = data['username'] passwd = data['password'] result = User.query.filter(User.name==username).first() if result: sql_pass_encrypt = generate_password_hash(result.password) if result.name == username and check_password_hash(sql_pass_encrypt,passwd): session['user'] = username return jsonify({"code": "200","data": ""}) return jsonify({"code": "500","data": "无效的用户名或密码!"}) return jsonify({"code":"300","data":"用户不存在!"}) @app.route('/') # 页面主页 def index(): return render_template('index.html',username=session['user']) if __name__ == '__main__': app.run()
调用关系:
# 注册蓝图
ops/__init__.py -> main/users
#引用配置文件
oss/__init__.py -> conf/default.py
# 加载数据库配置
run.py -> model/db.py