了解什么是蓝图
python中的蓝图就是将系统的代码模块化,比如登录模块管理登录注册修改密码,管理模块管理网站内容的增删改查等等,如果都写在一起会使代码非常的乱没有条理。
所以我们需要蓝图来对代码模块化,使得代码结构清晰,便于维护。
如何定义蓝图
从Flask中导入Blueprint,再创建一个实例即可。Blueprint接受两个参数,分别为蓝本的名字和蓝本所在的包或模块,大多数情况下第二个参数使用Python 的__name__ 变量即可。
from flask import Blueprint
admin = Blueprint("admin", __name__)
from app.admin.views import *
使用蓝图创建路由
from . import admin
@admin.route('/')
def index():
return "后台主页"
注册蓝图
创建app后,即可注册已创立的蓝图。
from flask import Flask
from app.admin import admin as admin_blueprint
from app.home import home as home_blueprint
from flask_script import Manager
app = Flask(__name__)
manager = Manager(app)
# 注册admin蓝图, url_prefix='/admin'添加前缀/admin
app.register_blueprint(admin_blueprint, url_prefix='/admin')
# 注册home蓝图, 不添加前缀
app.register_blueprint(home_blueprint)
项目:基于Flask的微电影管理网页(前半部分)
项目的结构
├── app
│ ├── admin
│ │ ├── forms.py
│ │ ├── __init__.py
│ │ └── views.py
│ ├── home
│ │ ├── forms.py
│ │ ├── __init__.py
│ │ └── views.py
│ ├── __init__.py
│ ├── models.py
│ ├── static
│ └── templates
├── doc
├── manage.py
└── requirement.txt
创建数据库,写配置文件
create database MovieProject default charset=utf8
#配置文件
# 数据库配置信息
SQLALCHEMY_DATABASE_URI = "mysql://root:redhat@localhost/MovieProject"
SQLALCHEMY_TRACK_MODIFICATIONS = True
# 表单的配置(CSRF)
SECRET_KEY = "WESTOS"
创建数据表
from datetime import datetime
from app import db
# 关联
# 1. 标签(1)和电影(n):
# 2. 电影(1)和评论(n)
# 3. 用户(1)和评论(n)
# 4. 用户(1)和用户登录日志(n)
# 5. 角色(1)和权限(n)
# 6. 角色(1)和管理员(n)
# 标签表
class Tag(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
name = db.Column(db.String(50), unique=True, index=True) # 标签名称, 不能重复;
addtime = db.Column(db.DateTime, default=datetime.utcnow()) # 创建时间
movies = db.relationship('Movie', backref='tag') # 反向关联, 让Movie表多一个属性, tag
def __repr__(self):
return "<Tag %s>" % (self.name)
# 电影表
class Movie(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
name = db.Column(db.String(50), unique=True, index=True) # 名称,不能重复;
addtime = db.Column(db.DateTime, default=datetime.utcnow()) # 创建时间
info = db.Column(db.Text) # 电影简介
star = db.Column(db.SmallInteger) # 电影的星级
area = db.Column(db.String(50)) # 地区
length = db.Column(db.String(20)) # 片长
release_time = db.Column(db.DateTime) # 上映时间
url = db.Column(db.String(200), unique=True) # 上传电影内容的url地址;
logo = db.Column(db.String(200), unique=True) # 上传电影封面的url地址;
tag_id = db.Column(db.Integer, db.ForeignKey('tag.id')) # 标签的外键关联
comments = db.relationship('Comment', backref="movie") # 电影和评论的反向引用
def __repr__(self):
return '<Movie %s>' % (self.name)
# 预告管理表
class Preview(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
name = db.Column(db.String(50), unique=True, index=True) # 名称, 不能重复;
addtime = db.Column(db.DateTime, default=datetime.utcnow()) # 创建时间
logo = db.Column(db.String(200), unique=True) # 上传预告封面的url地址;
def __repr__(self):
return "<Preview %s>" % (self.name)
# 会员管理数据库
class User(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
name = db.Column(db.String(30), unique=True)
password = db.Column(db.String(300))
email = db.Column(db.String(50), unique=True) # 邮箱地址
phone = db.Column(db.Integer, unique=True)
face = db.Column(db.String(50), unique=True) # 用户头像url地址
gender = db.Column(db.Boolean) # 性别
comments = db.relationship('Comment', backref='user') # 用户和评论的反向关联
userlogs = db.relationship('Userlog', backref='user') # 会员和会员登录日志的反向关联
def verify_password(self, password):
from werkzeug.security import check_password_hash
# 判断密码是否正确
return check_password_hash(self.password, password)
def __repr__(self):
return "<User %s>" % (self.name)
# 电影评论数据表: 评论和用户/电影关联
class Comment(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
content = db.Column(db.String(50), unique=True, index=True) # 评论的内容
addtime = db.Column(db.DateTime, default=datetime.utcnow()) # 创建时间
movie_id = db.Column(db.Integer, db.ForeignKey('movie.id')) # 电影和评论的外键关联
user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # 电影和用户的关联
def __repr__(self):
return "<Comment %s>" % (self.content[:6])
# 日志管理表
# 1. 会员登录日志表
# 2. 管理员登录日志表
# 3. 管理员操作日志表
#
class Userlog(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
addtime = db.Column(db.DateTime, default=datetime.utcnow()) # 创建时间
user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # 会员和会员登录日志之间的关联
ip = db.Column(db.String(30)) # 用户登录的ip
area = db.Column(db.String(50)) # 用户客户端登录所在的地理位置
def __repr__(self):
return 'Userlog %s' % (self.ip)
# 权限管理的数据库表
class Auth(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
addtime = db.Column(db.DateTime, default=datetime.utcnow()) # 创建时间
name = db.Column(db.String(30), unique=True) # 权限的名称
url = db.Column(db.String(50), unique=True) # 权限的url地址
role_id = db.Column(db.Integer, db.ForeignKey('role.id'))
def __repr__(self):
return '<Auth %s>' % (self.name)
# 角色管理
class Role(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
addtime = db.Column(db.DateTime, default=datetime.utcnow()) # 创建时间
name = db.Column(db.String(30), unique=True) # 角色的名称
auths = db.relationship('Auth', backref='role')
admins = db.relationship('Admin', backref='role')
def __repr__(self):
return '<Role %s>' % (self.name)
# 管理员数据表
class Admin(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
addtime = db.Column(db.DateTime, default=datetime.utcnow()) # 创建时间
name = db.Column(db.String(30), unique=True) # 名称
password = db.Column(db.String(100))
is_super = db.Column(db.Boolean, default=False) # 是否为超级管理员(可以做任何操作), 默认不是
role_id = db.Column(db.Integer, db.ForeignKey('role.id')) # 角色和管理员的关联
adminlogs = db.relationship("Adminlog", backref='admin') # 管理员登录日志
adminOplogs = db.relationship('AdminOplog', backref='admin') # 管理员操作日志
def __repr__(self):
return "<Admin %s>" %(self.name)
# 管理员登录日志
class Adminlog(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
addtime = db.Column(db.DateTime, default=datetime.utcnow()) # 创建时间
admin_id = db.Column(db.Integer, db.ForeignKey('admin.id')) # 管理员和管理员登录日志之间的关联
ip = db.Column(db.String(30)) # 登录的ip
area = db.Column(db.String(50)) # 客户端登录所在的地理位置
def __repr__(self):
return 'Adminlog %s' % (self.ip)
# 管理员操作日志
class AdminOplog(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
addtime = db.Column(db.DateTime, default=datetime.utcnow()) # 创建时间
admin_id = db.Column(db.Integer, db.ForeignKey('admin.id')) # 管理员和管理员登录日志之间的关联
content = db.Column(db.String(30)) # 管理员操作的内容
ip = db.Column(db.String(30)) # 登录的ip
area = db.Column(db.String(50)) # 客户端登录所在的地理位置
def __repr__(self):
return 'AdminOplog %s' % (self.ip)
前台部分
定义蓝图
from flask import Blueprint
# 定义蓝图
home = Blueprint("home", __name__)
from app.home.views import *
登录表单
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length
class LoginForm(FlaskForm):
username = StringField(
label="用户名",
validators=[
DataRequired()
]
)
password = PasswordField(
label="密码",
validators=[
DataRequired(),
Length(6, 12, message="密码长度必须为6-12")
]
)
submit = SubmitField(
label="登录"
)
前台视图函数
import json
import requests
from app.home.forms import LoginForm
# 导入home的蓝图对象
from . import home
from flask import render_template, flash, session, redirect, url_for, request
from werkzeug.security import generate_password_hash
@home.route('/')
def index():
return render_template('home/base.html')
@home.route('/login/', methods=['POST', 'GET'])
def login():
from app.models import User, Userlog
form = LoginForm()
if form.validate_on_submit():
username = form.username.data
password = form.password.data
user = User.query.filter_by(name=username).first()
if user and user.verify_password(password):
# session信息的保存
session['user_id'] = user.id
session['user'] = user.name
flash("用户%s登录成功" % (user.name))
remote_ip = request.remote_addr
Userlog(user_id=user.id,
ip=remote_ip,
area='xxx内网IP')
# 从index蓝图里面寻找index函数;
return redirect(url_for('home.index'))
else:
flash("用户登录失败")
return redirect(url_for('home.login'))
return render_template('home/login.html',
form=form)
注册home蓝图读取配置文件
from flask import Flask
from app.admin import admin as admin_blueprint
from app.home import home as home_blueprint
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
import pymysql
from flask_moment import Moment # 时间的问题解决
from flask_bootstrap import Bootstrap # 导入bootstrap样式
app = Flask(__name__)
manager = Manager(app)
bootstrap = Bootstrap(app)
# 数据库报错问题
pymysql.install_as_MySQLdb()
# 读取配置文件的配置信息
app.config.from_pyfile('../config.py')
db = SQLAlchemy(app)
moment = Moment(app)
# 注册home蓝图, 不添加前缀
app.register_blueprint(home_blueprint)