简介:
Bootstrap-Flask是一个简化在Flask项目中集成前端开源框架Bootstrap过程的Flask扩展。使用Bootstrap可以快速的创建简洁、美观又功能全面的页面,而Bootstrap-Flask让这一过程更加简单和高效。
安装:
pip install bootstrap-flask
初始化:
from flask_bootstrap import Bootstrap
from flask import Flask
app = Flask(__name__)
bootstrap = Bootstrap(app)
工厂函数穿件程序实例:
from flask_bootstrap import Bootstrap
from flask import Flask
bootstrap = Bootstrap()
def create_app():
app = Flask(__name__)
bootstrap.init_app(app)
return app
Bootstrap-Flask提供的功能
- 2个资源加载函数
在简单的示例程序中或者开发中,你可以使用他提供的两个快捷方法生成Bootstrap资源引用代码:
<head>
{{ bootstrap.load_css() }}
</head>
<body>
...
{{ bootstrap.load_js() }}
</body>
- 7个快捷渲染宏
目前,Bootstrap-Flask一共提供了7个宏,分别用来快捷渲染各类Bootstrap页面组件,并提供了对扩展Flask-WTF、Flask-SQLAlchemy的支持
使用方法简单,例如渲染Flask-WTF(WTForms) 的表单类的render_form()宏为例,你只需要从对应的模板路径导入宏,然后调用即可并传入必要参数:
- 用户信息修改提交表单函数
@user_bp.route('/settings/profile', methods=['GET', 'POST'])
# 用户重新验证登录获取一个新的session
@login_required
def edit_profile():
form = EditProfileForm()
# 如果用户点击了提交按钮对表单提交的字段进行验证,无误后更新数据库
if form.validate_on_submit():
current_user.name = form.name.data
current_user.username = form.username.data
current_user.bio = form.bio.data
current_user.website = form.website.data
current_user.location = form.location.data
db.session.commit()
# 修改成功后弹框提示修改成功
flash('Profile updated.', 'success')
# 自动跳转到主页,并修改渲染的用户名
return redirect(url_for('.index', username=current_user.username))
# 表单未修改时始终显示之前的用户信息
form.name.data = current_user.name
form.username.data = current_user.username
form.bio.data = current_user.bio
form.website.data = current_user.website
form.location.data = current_user.location
# 将用户数据渲染到表单中
return render_template('user/settings/edit_profile.html', form=form)
- 用户修改个人信息渲染模板
{% extends 'user/settings/base.html' %}
{% from 'bootstrap/form.html' import render_form %}
{% block title %}Edit Profile{% endblock %}
{% block setting_content %}
<div class="card w-100 bg-light">
<h3 class="card-header">Edit Profile</h3>
<div class="card-body">
{{ render_form(form) }}
</div>
</div>
{% endblock %}
利用reder_field()渲染表单字段
- 渲染用户发布的图片描述
@main_bp.route('/photo/<int:photo_id>')
def show_photo(photo_id):
photo = Photo.query.get_or_404(photo_id)
page = request.args.get('page', 1, type=int)
per_page = current_app.config['ALBUMY_COMMENT_PER_PAGE']
pagination = Comment.query.with_parent(photo).order_by(Comment.timestamp.asc()).paginate(page, per_page)
comments = pagination.items
comment_form = CommentForm()
description_form = DescriptionForm()
tag_form = TagForm()
description_form.description.data = photo.description
return render_template('main/photo.html', photo=photo, comment_form=comment_form,
description_form=description_form, tag_form=tag_form,
pagination=pagination, comments=comments)
- 用户发布图片信息渲染模板
<div id="description-form">
<form action="{{ url_for('.edit_description', photo_id=photo.id) }}" method="post">
{{ description_form.csrf_token }}
{{ render_field(description_form.description) }}
<a class="btn btn-light btn-sm" id="cancel-description">Cancel</a>
{{ render_field(description_form.submit, class='btn btn-success btn-sm') }}
</form>
</div>
- 利用render_pagination()宏渲染一个标准的分页导航部件:
@main_bp.route('/')
def index():
# 验证是否未登录状态
if current_user.is_authenticated:
# 获取参数page不传默认为1,强制转换类型
page = request.args.get('page', 1, type=int)
per_page = current_app.config['ALBUMY_PHOTO_PER_PAGE']
pagination = Photo.query \
.join(Follow, Follow.followed_id == Photo.author_id) \
.filter(Follow.follower_id == current_user.id) \
.order_by(Photo.timestamp.desc()) \
.paginate(page, per_page)
photos = pagination.items
else:
pagination = None
photos = None
tags = Tag.query.join(Tag.photos).group_by(Tag.id).order_by(func.count(Photo.id).desc()).limit(10)
return render_template('main/index.html', pagination=pagination, photos=photos, tags=tags, Collect=Collect)
这里关注的几个要点:
a. 路由中添加页面属性"/" ,这样网址中就可以添加页面参数
b. 函数添加参数page,默认值为1
c. 查询函数添加 .paginate(page, per_page),返回一个paginate对象
d. render_template 传入paginate对象,和数据信息paginate.items
# index.html渲染
{% if photos %}
{{ render_pagination(pagination, align='center') }}
{% endif %}
利用render_nav_item() 渲染一个 导航条目
- 导航条目 home, explore
{# 导入import render_nav_item #}
{% from 'bootstrap/nav.html' import render_nav_item %}
{# 导航栏点击 Home 渲染 main.index模板,点击Explore渲染 main.explore模 #}
<div class="navbar-nav mr-auto">
{{ render_nav_item('main.index', 'Home') }}
{{ render_nav_item('main.explore', 'Explore') }}
<form class="form-inline my-2 my-lg-0" action="{{ url_for('main.search') }}">
<input type="text" name="q" class="form-control mr-sm-1" placeholder="Photo, tag or user"
required>
<button class="btn btn-light my-2 my-sm-0" type="submit">
<span class="oi oi-magnifying-glass"></span>
</button>
</form>
</div>
利用 render_breadcrumb_item 渲染面包屑条目
{% from 'bootstrap/nav.html' import render_breadcrumb_item %}
{# 点击Dashboard Home 渲染 admin.index模板 #}
{# 点击Manage User 渲染 admin.manage_user模板 #}
{# 点击Edit Profile 渲染 admin.edit_profile_admin模板 #}
<ol class="breadcrumb">
{{ render_breadcrumb_item('admin.index', 'Dashboard Home') }}
{{ render_breadcrumb_item('admin.manage_user', 'Manage User') }}
{{ render_breadcrumb_item('admin.edit_profile_admin', 'Edit Profile') }}
</ol>