首页 > 编程学习 > 【Python百日进阶-WEB开发-冲進Flask】Day182 - Flask蓝图与模板继承

文章目录

  • 一、day02项目环境和结构搭建
    • 1.1 项目根目录创建apps包
    • 1.2 项目模板目录templates创建user子目录
  • 二、后端知识要点
    • 2.1 蓝图Blueprint基础知识
      • 2.1.1 为什么需要蓝图
      • 2.1.2 什么是蓝图
      • 2.1.3 蓝图的属性
      • 2.1.4 蓝图使用的步骤
        • 2.1.4.1 创建一个蓝图的包,例如user,并在view.py文件中创建蓝图对象
        • 2.1.4.2 view.py文件中创建当前蓝图使用的视图函数
        • 2.1.4.3 apps包的初始化文件__init__.py中新建创建应用app的函数,并绑定蓝图
        • 2.1.4.4 项目根目录app.py调用函数创建app对象
    • 2.2 request对象获取前端提交的数据
      • 2.2.1 接收前端两种方式提交的数据
      • 2.2.2 获取前端get方式提交的数据
      • 2.2.3 获取前端post方式提交的数据
    • 2.3 model.py定义类
      • 2.3.1 User类的定义
      • 2.3.2 User类的实例化
  • 三、前端知识要点
    • 3.1 HTML页面文件的结构安排
    • 3.2 创建基础母版模板base.html
    • 3.3 模板的继承
      • 3.3.1 继承基础母版base.html
      • 3.3.2 Block填坑
    • 3.4 取消超链接href,自定义js
  • 四、项目完整代码
    • 4.1 项目目录结构
    • 4.2 后端代码
      • 4.2.1 配置文件settings.py
      • 4.2.2 项目启动app.py
      • 4.2.3 user包初始化__init__.py
      • 4.2.4 user子应用model.py
      • 4.2.5 user子应用视图view.py
    • 4.3 前端代码
      • 4.3.1 项目基础母版base.html
      • 4.3.2 user子应用注册页面register.html
      • 4.3.3 user子应用用户展示页面
      • 4.3.4 user子应用用户更新页面update.html

一、day02项目环境和结构搭建

1.1 项目根目录创建apps包

包内包含__init__.py文件

1.2 项目模板目录templates创建user子目录

user子应用中用到的页面 html 文件全部放到 templates\user 子目录中。

二、后端知识要点

2.1 蓝图Blueprint基础知识

2.1.1 为什么需要蓝图

随着flask程序越来越复杂,我们需要对程序进行模块化的处理,以利于大项目的开发。

2.1.2 什么是蓝图

  • 蓝图(blueprint):是flask自带的一种开发模式,用于实现单个应用的视图、模板、静态文件的集合。
  • 蓝图就是模块化处理的类,类似于Django中的app-子应用。
  • 蓝图就是一个存储操作路由映射方法的容器,主要用来实现客户端请求和URL相互关联的功能。 在Flask中,使用蓝图可以帮助我们实现模块化应用的功能。

2.1.3 蓝图的属性

  • 一个项目可以具有多个Blueprint。
  • 可以将一个Blueprint注册到任何一个未使用的URL下比如 “/”、“/sample”或者子域名。
  • 在一个应用中,一个模块可以注册多次。
  • Blueprint可以单独具有自己的模板、静态文件或者其它的通用操作方法,它并不是必须要实现应用的视图和函数的。
  • 在一个应用初始化时,就应该要注册需要使用的Blueprint。

2.1.4 蓝图使用的步骤

2.1.4.1 创建一个蓝图的包,例如user,并在view.py文件中创建蓝图对象

from flask import Blueprint
user_bp = Blueprint('user', __name__)

2.1.4.2 view.py文件中创建当前蓝图使用的视图函数

  • 使用蓝图后,反向解析url_for()需要用蓝图的名称点出路由别名。
  • 使用蓝图后,模板渲染需要从templates文件夹开始指定html文件目录,可能包括多层目录。
@user_bp.route('/')
def user_center():# print(url_for('user.register'))     # 反向解析需要加上蓝图名称return render_template('user/show.html', users=users)

2.1.4.3 apps包的初始化文件__init__.py中新建创建应用app的函数,并绑定蓝图

  • 因为创建蓝图,改变了Flask默认目录结构,所以初始化app时需要重新指定模板和静态文件目录。
  • 蓝图必须在初始化app时绑定到app上,才能发挥作用。
from flask import Flask
import settings
from apps.user.view import user_bpdef create_app():app = Flask(__name__,template_folder='../templates',static_folder='../static',)app.config.from_object(settings)# 将蓝图对象绑定到appapp.register_blueprint(user_bp)print(app.url_map)return app

2.1.4.4 项目根目录app.py调用函数创建app对象

  • 调用函数创建app对象可以保持启动文件的干净、清爽。
from apps import create_appapp = create_app()if __name__ == '__main__':app.run(port=5002)

2.2 request对象获取前端提交的数据

2.2.1 接收前端两种方式提交的数据

  • 蓝图路由中添加参数:methods=[‘GET’, ‘POST’]
  • 反向解析默认的名称为函数名(如user_update);如果函数名较长,可以指定别名endpoint=‘update’。
  • 每种方式都必须有返回值,否则会报错。
@user_bp.route('/update', methods=['GET', 'POST'], endpoint='update')
def user_update():if request.method == 'POST':# 获取post提交的数据username = request.form.get('username')return redirect('/')if request.method == 'GET':# 获取get提交的数据username = request.args.get('username')return render_template('user/update.html')

2.2.2 获取前端get方式提交的数据

  • get(‘username’) 与前端的 name='username’对应
username = request.args.get('username')

2.2.3 获取前端post方式提交的数据

username = request.form.get('username')

2.3 model.py定义类

2.3.1 User类的定义

  • 注意:类名首字母大写
class User:def __init__(self, username, password, phone=None):self.username = usernameself.password = passwordself.phone = phonedef __str__(self):return self.username

2.3.2 User类的实例化

  • 注意:类名首字母大写
from apps.user.model import User
user = User(username, password, phone)

三、前端知识要点

3.1 HTML页面文件的结构安排

  • 基础母版文件base.html放到模板文件夹中:day02\templates
  • user子应用的html文件放到模板文件夹的下级目录中:day02\templates\user

3.2 创建基础母版模板base.html

  1. html框架
  2. 预留标题block(title)
  3. 预留css样式block(mycss)
  4. 预留页面顶端block(head)
  5. 预留页面中部主体block(middel)
  6. 预留页面尾部block(foot)
  7. 预留javascript block(myjs)
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>{% block title %} 用户中心 {% endblock %}</title>{% block mycss %}{% endblock %}</head><body><div id="head"><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>{% block head%}{% endblock %}</div><div id="middle">{% block middle %}{% endblock %}</div><div id="foot">{% block foot%}{% endblock %}</div>{% block myjs %}{% endblock %}</body>
</html>

3.3 模板的继承

3.3.1 继承基础母版base.html

  • {% extends ‘base.html’ %} 一般放在子页面的第一行
  • 项目所有html文件的起始查找目录,都是基于app初始化时的templates文件夹
{% extends 'base.html' %}

3.3.2 Block填坑

{% block title %}用户展示
{% endblock %}{% block middle %}<span>当前用户人数时:{{ users|length }} 人</span><ul>{% for user in users %}<li>{{user.username}}-{{user.password}}-{{user.phone}}</li>{% endfor %}</ul><table border="solid 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 type="text/javascript">function del(username){// console.log(username)// location 地址栏对象location.href = '/del?username=' + username}function update(username){location.href = '/update?username=' + username}</script>
{% endblock %}

3.4 取消超链接href,自定义js

  • href=“javascript:;” 为取消超链接
  • οnclick=“del(‘{{ user.username }}’)” 为自定义js函数名称,特别注意:参数如果为字符串,需要双层引号。
  • js函数参数接收和python相同,放到圆括号中。
  • js中,location.href相当于重定向,可以拼接 路由 + ? + 变量名=value
<a href="javascript:;" onclick="del('{{ user.username }}')">删除</a><script type="text/javascript">function del(username){// console.log(username)// location 地址栏对象location.href = '/del?username=' + username}
</script>

四、项目完整代码

4.1 项目目录结构

在这里插入图片描述

4.2 后端代码

4.2.1 配置文件settings.py

# 配置文件ENV = 'development'
DEBUG = True

4.2.2 项目启动app.py

from apps import create_appapp = create_app()if __name__ == '__main__':app.run(port=5002)

4.2.3 user包初始化__init__.py

from flask import Flask
import settings
from apps.user.view import user_bpdef create_app():app = Flask(__name__,template_folder='../templates',static_folder='../static',)app.config.from_object(settings)# 将蓝图对象绑定到appapp.register_blueprint(user_bp)print(app.url_map)return app

4.2.4 user子应用model.py

class User:def __init__(self, username, password, phone=None):self.username = usernameself.password = passwordself.phone = phonedef __str__(self):return self.username

4.2.5 user子应用视图view.py

from flask import Blueprint, request, render_template, redirect, url_for
from apps.user.model import Useruser_bp = Blueprint('user', __name__)# 列表保存用户对象
users = []@user_bp.route('/')
def user_center():# print(url_for('user.register'))     # 反向解析需要加上蓝图名称return render_template('user/show.html', users=users)@user_bp.route('/register', methods=['GET', 'POST'])
def register():if request.method == 'POST':# 获取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:msg = '用户名已存在!'print(msg)return render_template('user/register.html', msg=msg)#4.4蓝图1:04:35# 创建user对象user = User(username, password, phone)# 添加到用户列表users.append(user)# print(users)return redirect('/')else:return render_template('user/register.html', msg='密码不一致!')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():# 获取传递过来的usernameusername = request.args.get('username')# 根据username找到列表中的对象for user in users:if user.username == username:users.remove(user)return redirect('/')else:return '删除失败'@user_bp.route('/update', methods=['GET', 'POST'], endpoint='update')
def user_update():if request.method == 'POST':# post请求realname = request.form.get('realname')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('user/update.html', msg='用户名重复!')else:for user in users:if user.username == realname:user.username = usernameuser.phone = phonereturn redirect('/')else:# get请求username = request.args.get('username')for user in users:# 匹配用户if user.username == username:return render_template('user/update.html', user=user)

4.3 前端代码

4.3.1 项目基础母版base.html

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>{% block title %} 用户中心 {% endblock %}</title><style type="text/css">#head {height: 3.125rem;background-color: bisque;}#head ul li {float: left;width: 6.25rem;text-align: center;font-size: 1.125rem;height: 3.125rem;line-height: 3.125rem;}#middle {height: 56.25rem;background-color: azure;}#foot {height: 3.125rem;line-height: 3.125rem;background-color: darkseagreen;}</style>{% block mycss %}{% endblock %}</head><body><div id="head"><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="foot"></div>{% block myjs %}{% endblock %}</body>
</html>

4.3.2 user子应用注册页面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 %}

在这里插入图片描述

4.3.3 user子应用用户展示页面

{% extends 'base.html' %}
{% block title %}用户展示
{% endblock %}{% block middle %}<span>当前用户人数时:{{ users|length }} 人</span><ul>{% for user in users %}<li>{{user.username}}-{{user.password}}-{{user.phone}}</li>{% endfor %}</ul><table border="solid 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 type="text/javascript">function del(username){// console.log(username)// location 地址栏对象location.href = '/del?username=' + username}function update(username){location.href = '/update?username=' + username}</script>
{% endblock %}

在这里插入图片描述

4.3.4 user子应用用户更新页面update.html

{% extends 'base.html' %}{% block title %}用户信息修改
{% endblock %}{% block middle %}<h1>用户信息更新</h1><p style="color: red">	{{ msg }}</p><form action="{{ url_for('user.update') }}" method="post"><p><input type="hidden" name="realname" id="" 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 }}" disable></p><p><input type="number" name="phone" placeholder="手机号码" value="{{ user.phone }}"></p><p><input type="submit" value="用户更新"></p></form>
{% endblock %}

在这里插入图片描述
在这里插入图片描述


本文链接:https://www.ngui.cc/article/show-701454.html
Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000