本文将基于前第三章的知识点以及蓝图,讲解一个以flask框架实现的简单登录注册业务。
当业务量越来越多的时候,不同业务中很容易出现多个以add、insert、update、delete这样的词命名的路由,这样就让路由名变得难以控制。因此在Flask框架中引入了蓝图的概念,每个业务都属于一个蓝图,在每个蓝图下都可以有add、insert这样命名的路由,但是在同一个蓝图下不能有相同的路由名。蓝图概念的出现很大程度简化了整个应用程序,对应用组件进行分割,使应用组件尽可能实现低耦合,含有以下特点:
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)
我们都知道web项目框架的三大组成:MVC,即model(模型)、view(视图)以及controller(控制器)。在flask的app文件夹下,抽离出了每个不同的业务代码,如用户业务,商品业务等,在每个业务下,又抽离出了model存放数据模型,controller控制业务逻辑和跳转视图。而与app同级的文件夹下存放着每个跳转的view视图界面。
首先,我们创建一个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>Titletitle>
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 %}
结果: