项目背景
一个紧急的项目,项目背景是客户突然想要将目前调用的所有API接口整合起来,需要能最大限度的控制接口的数据输出融合成一个API接口来调用,用以减少请求次数,由于项目紧急仅仅给了5天时间,经过紧急的设计与构思决定应用Graphql API的方式进行整合,因为某些原因初步敲定使用Python语言搭配Flask框架进行开发,经过4天的紧急开发调试,终于完成并上线,可以供给客户进行正常使用,但是由于开发的比较急,未开发后台相关的功能,导致修改数据库过于复杂,仅依靠类似Navicat等工具进行更改,但是表结构过于复杂,每次更改都非常的麻烦,需要开发一套简易后台管理系统,来管理数据库的增删改查因为是基于Flask框架编写的,经过查询准备使用现有的flask-admin构建后台,使用flask-login进行登录控制,但是搜遍所有的可搜的博客,文章都没有找到完整的项目供给参考[也有可能是真的没有找到],故经过几天的摸索与开发,才将后台构建好,再次与诸位分享构建方法,以供需要的人使用!
安装方法
# Flaskpip install Flask# flask-sqlalchemypip install Flask-SQLAlchemy# flask-adminpip install Flask-Admin# flask-loginpip install Flask-Login# wtformspip install WTForms# flask_scriptpip install Flask-Script
项目所用模块
Flask # 框架模块flask-sqlalchemy # ormflask-admin # 后台管理模块flask-login # 控制登录和认证模块flask_script # 执行外部脚本wtforms # 生成表单以及验证模块
项目结构为
|test|———templates # 存放项目前端模板 |————admin |————index.html |————index.html |————my_master.html|————app.py # 所有主要逻辑|————manage.py # 存放外部脚本
PS:具体详见截图
![510b88ca675cd53cb509d7e8772cda3f.png](https://i-blog.csdnimg.cn/blog_migrate/1b6b172721355d5af89bbdc1ae200ff5.jpeg)
项目结构图
详细实现逻辑
文件路径 test>templates>admin>index.html
{% extends 'admin/master.html' %}{% block body %}{{ super() }}
{% if current_user.is_authenticated %}
Flask-Admin test
Authentication
欢迎你使用Flask-Admin做后台哦!!!!!!!!!!!
{% else %} {{ form.hidden_tag() if form.hidden_tag }} {% for f in form if f.type != 'CSRFTokenField' %}
{{ f.label }} {{ f }} {% if f.errors %}
{% for e in f.errors %} {{ e }} {% endfor %} {% endif %}
{% endfor %} Submit {{ link | safe }} {% endif %}
Back
{% endblock body %}
文件路径 test>templates>index.html
Go to admin!
文件路径 test>templates>my_master.html
{% extends 'admin/base.html' %}{% block access_control %}{% if current_user.is_authenticated %}
{{ current_user.login }}
Log out
{% endif %}{% endblock %}
文件路径 test>app.py
import osimport pymysqlfrom flask import Flask, url_for, redirect, render_template, requestfrom flask_sqlalchemy import SQLAlchemyfrom wtforms import form, fields, validatorsimport flask_admin as adminimport flask_login as loginfrom flask_admin.contrib import sqlafrom flask_admin import helpers, exposefrom werkzeug.security import generate_password_hash, check_password_hash# 创建Flask应用程序app = Flask(__name__)# 创建虚拟密钥,以便我们可以使用会话app.config['SECRET_KEY'] = '123456790'# 创建mysql数据库MYSQL_USER = "root"MYSQL_PASSWORD = "111111"MYSQL_DATABASE = "test2"MYSQL_IP = "127.0.0.1"MYSQL_PROT = 3306DB_URI = "mysql+pymysql://{username}:{password}@{host}:{port}/{db}?charset=utf8".format(username=MYSQL_USER, password=MYSQL_PASSWORD, host=MYSQL_IP, port=MYSQL_PROT, db=MYSQL_DATABASE)app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = Falseapp.config['SQLALCHEMY_DATABASE_URI'] = DB_URIapp.config['SQLALCHEMY_ECHO'] = False # 用于控制是否展示sql调试过程db = SQLAlchemy(app)# 创建用户模型。class User(db.Model): id = db.Column(db.Integer, primary_key=True) first_name = db.Column(db.String(100)) last_name = db.Column(db.String(100)) login = db.Column(db.String(80), unique=True) email = db.Column(db.String(120)) password = db.Column(db.String(1024)) @property def is_authenticated(self): return True @property def is_active(self): return True @property def is_anonymous(self): return False def get_id(self): return self.id # 管理界面必需 def __unicode__(self): return self.username# 定义登录和注册表格(用于flask登录)class LoginForm(form.Form): login = fields.StringField(validators=[validators.required()]) password = fields.PasswordField(validators=[validators.required()]) def validate_login(self, field): user = self.get_user() if user is None: raise validators.ValidationError('Invalid user') # 我们正在将纯文本password与数据库中的哈希值进行比较 if not check_password_hash(user.password, self.password.data): raise validators.ValidationError('Invalid password') def get_user(self): return db.session.query(User).filter_by(login=self.login.data).first()class RegistrationForm(form.Form): login = fields.StringField(validators=[validators.required()]) email = fields.StringField() password = fields.PasswordField(validators=[validators.required()]) def validate_login(self, field): if db.session.query(User).filter_by(login=self.login.data).count() > 0: raise validators.ValidationError('Duplicate username')# 初始化 flask-logindef init_login(): login_manager = login.LoginManager() login_manager.init_app(app) # 创建用户加载器功能 @login_manager.user_loader def load_user(user_id): return db.session.query(User).get(user_id)# 创建自定义模型视图类class MyModelView(sqla.ModelView): def is_accessible(self): return login.current_user.is_authenticated# 创建处理登录和注册的自定义索引视图类class MyAdminIndexView(admin.AdminIndexView): @expose('/') def index(self): if not login.current_user.is_authenticated: return redirect(url_for('.login_view')) return super(MyAdminIndexView, self).index() @expose('/login/', methods=('GET', 'POST')) def login_view(self): # 处理用户登录 form = LoginForm(request.form) if helpers.validate_form_on_submit(form): user = form.get_user() login.login_user(user) if login.current_user.is_authenticated: return redirect(url_for('.index')) link = '
Don't have an account? Click here to register.
' self._template_args['form'] = form self._template_args['link'] = link return super(MyAdminIndexView, self).index() @expose('/register/', methods=('GET', 'POST')) def register_view(self): form = RegistrationForm(request.form) if helpers.validate_form_on_submit(form): user = User() form.populate_obj(user) # 我们对用户密码进行哈希处理,以避免在数据库中将其另存为纯文本, user.password = generate_password_hash(form.password.data) db.session.add(user) db.session.commit() login.login_user(user) return redirect(url_for('.index')) link = '
Already have an account? Click here to log in.
' self._template_args['form'] = form self._template_args['link'] = link return super(MyAdminIndexView, self).index() @expose('/logout/') def logout_view(self): login.logout_user() return redirect(url_for('.index'))# Flask views@app.route('/')def index(): return render_template('index.html')# 初始化 flask-logininit_login()# 创建 adminadmin = admin.Admin(app, 'Auth test', index_view=MyAdminIndexView(), base_template='my_master.html')# 添加 viewadmin.add_view(MyModelView(User, db.session))if __name__ == '__main__': # 启动 app.run(debug=True)
文件路径 test>manage.py
from flask_script import Managerfrom app import appfrom app import dbfrom app import Userfrom werkzeug.security import generate_password_hashmanager = Manager(app)@manager.commanddef build_sample_db(): """ Populate a small db with some example entries. """ import string import random db.drop_all() db.create_all() # 密码经过哈希处理 test_user = User(login="test", password=generate_password_hash("test")) db.session.add(test_user) first_names = [ 'Harry', 'Amelia', 'Oliver', 'Jack', 'Isabella', 'Charlie', 'Sophie', 'Mia', 'Jacob', 'Thomas', 'Emily', 'Lily', 'Ava', 'Isla', 'Alfie', 'Olivia', 'Jessica', 'Riley', 'William', 'James', 'Geoffrey', 'Lisa', 'Benjamin', 'Stacey', 'Lucy' ] last_names = [ 'Brown', 'Smith', 'Patel', 'Jones', 'Williams', 'Johnson', 'Taylor', 'Thomas', 'Roberts', 'Khan', 'Lewis', 'Jackson', 'Clarke', 'James', 'Phillips', 'Wilson', 'Ali', 'Mason', 'Mitchell', 'Rose', 'Davis', 'Davies', 'Rodriguez', 'Cox', 'Alexander' ] for i in range(len(first_names)): user = User() user.first_name = first_names[i] user.last_name = last_names[i] user.login = user.first_name.lower() user.email = user.login + "@example.com" user.password = generate_password_hash( ''.join(random.choice(string.ascii_lowercase + string.digits) for i in range(10))) db.session.add(user) db.session.commit()if __name__ == "__main__": manager.run()
关于启动和生成虚拟数据的方法
1、cd 到 test目录中2、执行 python manage.py build_sample_db 来初始化 数据表并添加相关的测试数据3、启动系统命令为 python manage.py runserver -h 127.0.0.1 -p 8080
结尾
如果大家有什么更好的办法和点子或者发现代码中有什么错误或漏洞,欢迎大家留言交流!!!!
#科技新星创作营##python#
![c048d46fbcfc13f4bb06721a7a164aef.png](https://i-blog.csdnimg.cn/blog_migrate/ef6a5baed311f23a4bb8c8ef7503b576.jpeg)
![ec820f49d31099652238b26a87a26939.png](https://i-blog.csdnimg.cn/blog_migrate/cb8ea426868065a1157f4be5bfee7a24.jpeg)
![deaa208356eb1a8907ff91b0c9fac0fb.png](https://i-blog.csdnimg.cn/blog_migrate/ce2042499880ec1b0f6be11412dbe756.jpeg)