当前位置:网站首页>Flask框架初学-04-flask蓝图及代码抽离
Flask框架初学-04-flask蓝图及代码抽离
2022-07-26 09:59:00 【流墨馨】
本文将基于前第三章的知识点以及蓝图,讲解一个以flask框架实现的简单登录注册业务。
蓝图
当业务量越来越多的时候,不同业务中很容易出现多个以add、insert、update、delete这样的词命名的路由,这样就让路由名变得难以控制。因此在Flask框架中引入了蓝图的概念,每个业务都属于一个蓝图,在每个蓝图下都可以有add、insert这样命名的路由,但是在同一个蓝图下不能有相同的路由名。蓝图概念的出现很大程度简化了整个应用程序,对应用组件进行分割,使应用组件尽可能实现低耦合,含有以下特点:
- 把一个应用分解为一个蓝图的集合,一个蓝图下面可以有很多个路由,不同蓝图下可以有相同路由(可通过蓝图进行区分)
- 在一个应用中用不同的 URL 规则多次注册一个蓝图
- 通过蓝图提供模板过滤器、静态文件、模板和其它功能
- 初始化一个 Flask 扩展时,在这些情况中注册一个蓝图
蓝图实现步骤:
1、在视图中申明创建一个蓝图
# 声明一个路由前缀为user,名字为user_bp的蓝图 第一个参数为:url_prefix
user_bp = Blueprint('user',__name__)
2、在app中注册蓝图
# 在Flask的核心对象app中申明template、static的存放地址,即蓝图文件夹的路径
app = Flask('不同蓝图的文件夹路径',__name__,template_folder='../templates',static_folder='../static')
# 注册关联蓝图
app.register_blueprint(user_bp)
# 打印出app下的url
print(app.url_map)
# 查看资源文件夹内容
print(user.root_path)
Example
我们都知道web项目框架的三大组成:MVC,即model(模型)、view(视图)以及controller(控制器)。在flask的app文件夹下,抽离出了每个不同的业务代码,如用户业务,商品业务等,在每个业务下,又抽离出了model存放数据模型,controller控制业务逻辑和跳转视图。而与app同级的文件夹下存放着每个跳转的view视图界面。
项目整体框架(此处view.py为控制层):
首先,我们创建一个settings.py存放配置信息
# 配置文件
ENV = 'development'
DEBUG = True
在app包下的__init__.py中创建一个create_app方法,这个方法的主要作用是抽离出app.py的创建flask实例以及一些模块间关联的代码。实例化Flask时可以指定templates和static文件夹的存放路径,蓝图根据视图控制的增加而增加,这里是关联了一个用户的蓝图
from flask import Flask
import settings
from app.user.view import user_bp
def create_app():
# app是一个核心对象,此处创建
app = Flask(__name__,template_folder='../templates',static_folder='../static')
# 加载配置
app.config.from_object(settings)
# 蓝图关联
app.register_blueprint(user_bp)
print(app.url_map)
return app
编写app.py文件,这个文件是一个启动文件,是整个程序启动的关键
from app import create_app
app = create_app()
if __name__ == '__main__':
app.run()
创建一个model.py,编写User类,
class User:
def __init__(self,username,password,phone=None):
self.username = username
self.password = password
self.phone = phone
def __str__(self):
return self.username
编写view.py,里面注册了一个名为user的蓝图,以及注册、登录、退出、修改、删除、展示方法
from flask import Flask, Blueprint, request, render_template
from werkzeug.utils import redirect
from app.user.model import User
user_bp = Blueprint('user',__name__)
users = []
@user_bp.route('/')
def user_center():
return render_template('user/show.html',users=users)
@user_bp.route('/register',methods=['GET','POST'])
def register():
if request.method == 'POST':
# 获取数据
username = request.form.get('username')
password = request.form.get('password')
repassword = request.form.get('repassword')
phone = request.form.get('phone')
if password == repassword:
# 用户唯一
for user in users:
if user.username == username:
return render_template('user/register.html',msg='用户名已存在!')
# 创建user对象
user = User(username,password,phone)
# 添加到用户列表
users.append(user)
return redirect('/')
return render_template('user/register.html')
@user_bp.route('/login',methods=['GET','POST'])
def login():
return '用户登录'
@user_bp.route('/logout',methods=['GET','POST'])
def logout():
return '用户退出'
@user_bp.route('/del')
def del_user():
# 获取传递的username
username = request.args.get('username')
# 根据username找到列表中的user对象
for user in users:
if user.username == username:
# 删除user
users.remove(user)
return redirect('/')
else:
return '删除失败!'
@user_bp.route('/update',methods=['GET','POST'],endpoint='update')
def update_user():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
phone = request.form.get('phone')
for user in users:
if user.username == username:
return render_template('show.html',user=user)
else:
username = request.args.get('username')
for user in users:
if user.username == username:
return render_template('user/register.html',user=user)
return
跳转父视图 base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %} 用户中心 {% endblock %}</title>
<style> </style>
{% block mycss %}
{% endblock %}
</head>
<body>
<div id="header">
<ul>
<li><a href="">首页</a></li>
<li><a href="">秒杀</a></li>
<li><a href="">超市</a></li>
<li><a href="">图书</a></li>
<li><a href="">会员</a></li>
</ul>
</div>
<div id="middle">
{% block middle %}
{% endblock %}
</div>
<div id="footer"></div>
{% block myjs %}
{% endblock %}
</body>
</html>
跳转视图 register.html
{% extends 'base.html' %}
{% block title %}
用户注册
{% endblock %}
{% block middle %}
<p style="color: red">{
{ msg }}</p>
<form action="{
{url_for('user.register')}}" method="post">
<p><input type="text" name="username" placeholder="用户名"></p>
<p><input type="password" name="password" placeholder="密码"></p>
<p><input type="password" name="repassword" placeholder="确认密码"></p>
<p><input type="number" name="phone" placeholder="手机号码"></p>
<p><input type="submit" value="用户注册"></p>
</form>
{% endblock %}
跳转视图 login.html 未处理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>
跳转视图 show.html
{% extends 'base.html' %}
{% block middle %}
<h1>用户信息</h1>
<span>当前用户人数是:{
{ users | length }} 人</span>
<table border="1" cellspacing="0" width="60%">
{% for user in users %}
<tr>
<td>{
{ loop.index }}</td>
<td>{
{ user.username }}</td>
<td>{
{ user.password }}</td>
<td>{
{ user.phone }}</td>
<td><a href="javascript:;" onclick="update('{
{ user.username }}')">修改</a><a href="javascript:;" onclick="del('{
{ user.username }}')">删除</a> </td>
</tr>
{% endfor %}
</table>
{% endblock %}
{% block myjs %}
<script> // 删除用户 function del(username){
// console.log(username) location.href = '/del?username'+username' } // 修改用户信息 function update(username){
alert(username) console.log(username) location.href = '/update?username'+username' } </script>
{% endblock %}
跳转视图 update.html
{% extends 'base.html' %}
{% block title %}
用户信息修改
{% endblock %}
{% block middle %}
<h1>用户信息更新</h1>
<form action="{
{ url_for('user.update') }}" method="post">
<p><input type="hidden" name="realname" value="{
{ user.username }}"></p>
<p><input type="text" name="username" placeholder="用户名" value="{
{ user.username }}"></p>
<p><input type="text" name="password" placeholder="密码" value="{
{ user.password }}" disabled></p>
<p><input type="text" name="pone" placeholder="手机号码" value="{
{ user.phone }}"></p>
<p><input type="submit" value=""></p>
</form>
{% endblock %}
{% block %}
{% endblock %}
结果:



边栏推荐
- In Net 6.0
- IE7 set overflow attribute failure solution
- 编写一个在bash / shell 和 PowerShell中均可运行的脚本
- Fiddler download and installation
- Xiaobai makes a wave of deep copy and shallow copy
- Matlab Simulink realizes fuzzy PID control of time-delay temperature control system of central air conditioning
- Uni app learning summary
- IIS error prompt after installing Serv-U: hresult:0x80070020
- 2022 zhongkepan cloud - server internal information acquisition and analysis flag
- Netease cloud UI imitation -- & gt; sidebar
猜你喜欢

PMM (percona monitoring and management) installation record

Search module use case writing

2021年山东省中职组“网络空间安全”B模块windows渗透(解析)

AR model in MATLAB for short-term traffic flow prediction

Installation and use of cocoapods

在Blazor 中自定义权限验证

2022年中科磐云——服务器内部信息获取 解析flag

Interview shock 68: why does TCP need three handshakes?

El table implements adding / deleting rows, and a parameter changes accordingly

服务器内存故障预测居然可以这样做!
随机推荐
Uni app learning summary
Fuzzy PID control of motor speed
2021 windows penetration of "Cyberspace Security" B module of Shandong secondary vocational group (analysis)
In Net 6.0
在.NET 6.0中配置WebHostBuilder
Antd treeselect gets the value of the parent node
30分钟彻底弄懂 synchronized 锁升级过程
在同一conda环境下先装Pytroch后装TensorFlow
MFC handy notes
Getting started with SQL - combined tables
PHP executes shell script
Docker configuring MySQL Cluster
JS continuous assignment operation
The problem of accessing certsrv after configuring ADCs
In the same CONDA environment, install pytroch first and then tensorflow
Interview shock 68: why does TCP need three handshakes?
新公链Aptos何以拉满市场期待值?
Mo team learning summary (II)
服务发现原理分析与源码解读
Wechat applet learning notes 2