本篇博客介绍flask中Bootstrap的使用,因为前端页面编写不是我们的主要目标,这里仅提供一些简陋的页面以作参考。
本篇博客参考内容:
https://github.com/greyli/bluelog
https://www.cnblogs.com/hippieZhou/p/10593552.html
1.相关库安装
pip install bootstrap-flask
2.相关代码
在extensions.py中添加bootstrap的实例:
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_bootstrap import Bootstrap
db = SQLAlchemy()
migrate = Migrate()
bootstrap = Bootstrap()
__init__.py中的初始化代码修改如下:
from flask import Flask
from myblog.home.blog import blog_bp
from myblog.extensions import db, migrate, bootstrap
from myblog.config import Config
def create_app():
app = Flask(__name__)
app.config.from_object(Config)
register_blueprints(app)
register_extensions(app)
return app
def register_blueprints(app):
app.register_blueprint(blog_bp)
def register_extensions(app):
db.init_app(app)
db.create_all(app=app)
migrate.init_app(app, db)
bootstrap.init_app(app)
blog.py中的视图函数修改如下:
from flask import request, Blueprint, render_template
from myblog.models import Article, Category, Comment
from myblog.utils import fake_all
blog_bp = Blueprint('blog', __name__)
@blog_bp.route('/')
@blog_bp.route('/index')
def index():
page = request.args.get('page', 1, type=int)
articles = Article.query.order_by(Article.timestamp.desc()).paginate(page, 5, False)
categories = Category.query.all()
return render_template('blog/index.html', articles=articles, categories=categories)
@blog_bp.route('/article/<int:article_id>')
def article(article_id):
article = Article.query.filter(Article.id == article_id).first()
return render_template('blog/article.html', article=article)
@blog_bp.route('/category/<int:category_id>')
def category(category_id):
page = request.args.get('page', 1, type=int)
articles = Article.query.filter(Article.category_id==category_id).order_by(Article.timestamp.desc()).paginate(page, 5, False)
return render_template('blog/category.html', articles=articles, category_id=category_id)
3.页面编写
在templates目录下新建base.html(存放公用的导航栏和加载bootstrap等)、新建blog文件夹,在blog文件夹下新建index.html、article.html、category.html,分别为博客首页、文章内容页、文章分类页,其中博客首页和文章分类页使用paginate实现了分页效果。
在static目录下添加一个网站的ico格式图片资源,取名为 favicon.ico,整个目录结构变更如下:
![](https://img2020.cnblogs.com/blog/1709480/202009/1709480-20200928141006453-1311148731.png)
base.html:
<!DOCTYPE html>
<html lang="en">
<head>
{% block head %}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
{% block styles %}
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}"> {{ bootstrap.load_css() }}
{% endblock %}
<title>{% block title %}{% endblock %}</title>
{% endblock %}
</head>
<body>
{% block nav %}
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<a class="navbar-brand" href="#">我的博客</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item {% if request.endpoint == 'blog.index' %} active {% endif %}">
<a class="nav-link" href="{{ url_for('blog.index') }}">首页<span class="sr-only">(current)</span></a>
</li>
</ul>
<ul class="navbar-nav">
<li class="nav-item {% if request.endpoint == 'blog.index' %} active {% endif %}">
<a class="nav-link" href="{{ url_for('blog.index') }}">登录</a>
</li>
</ul>
</div>
</div>
</nav>
{% endblock nav %}
<div class="container">
{% block content %}{% endblock%}
</div>
{% block scripts %}
{{ bootstrap.load_js() }}
{% endblock %}
</body>
</html>
index.html:
{% extends 'base.html' %}
{% block title %}
Index
{% endblock %}
{% block content %}
<div class="row">
<div class="col-sm-8">
{% for article in articles.items %}
<br />
<div class="alert alert-warning">
<h4 class="text-primary">
<a href="{{ url_for('blog.article', article_id=article.id) }}">{{ article.title }}</a>
</h4>
<blockquote>
<small>
<strong>Category: </strong><a href="{{ url_for('blog.category', category_id=article.category.id) }}">{{ article.category.name }}</a>
<span class="float-right">{{ article.timestamp }}</span>
</small>
</blockquote>
</div>
{% endfor %}
<nav aria-label="Page navigation example" class="m-4">
<ul class="pagination justify-content-center">
<li class="page-item {% if not articles.has_prev %}disabled{% endif %}">
<a class="page-link" href="{{ url_for('blog.index', page=articles.prev_num) }}">上一页</a>
</li>
{% for page in articles.iter_pages(1,1,3,2) %}
{% if page %}
<li class="page-item {%if page==articles.page%}active{%endif%}">
<a class="page-link" href="{{ url_for('blog.index',page=page) }}">{{page}}</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#">…</a>
</li>
{% endif %}
{% endfor %}
<li class="page-item {% if not articles.has_next %}disabled{% endif %}">
<a class="page-link" href="{{ url_for('blog.index',page=articles.next_num) }}">下一页</a>
</li>
</ul>
</nav>
</div>
<div class="col-sm-4 sidebar">
<br />
<div class="card mb-3">
<div class="card-header">Categories</div>
<ul class="list-group list-group-flush">
{% for category in categories %}
<li class="list-group-item list-group-item-action d-flex justify-content-between align-items-center">
<a href="{{ url_for('blog.category', category_id=category.id) }}">
{{ category.name }}
</a>
<span class="badge badge-primary badge-pill"> {{ category.articles|length }}</span>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% endblock %}
article.html:
{% extends 'base.html' %}
{% block title %}
Article
{% endblock %}
{% block content %}
<br />
<div class="alert alert-warning">
<h4 class="text-primary">{{ article.title }}</h4>
<br />
{{ article.body }}
<br />
<br />
<blockquote>
<small>
<strong>Category: </strong><a href="{{ url_for('blog.category', category_id=article.category.id) }}">{{ article.category.name }}</a>
<span class="float-right">{{ article.timestamp }}</span>
</small>
</blockquote>
</div>
{% endblock %}
category.html:
{% extends 'base.html' %}
{% block title %}
Category
{% endblock %}
{% block content %}
<div class="col-sm-8">
{% for article in articles.items %}
<br />
<div class="alert alert-warning">
<h4 class="text-primary">
<a href="{{ url_for('blog.article', article_id=article.id) }}">{{ article.title }}</a>
</h4>
<blockquote>
<small>
<strong>Category: </strong><a href="{{ url_for('blog.category', category_id=article.category.id) }}">{{ article.category.name }}</a>
<span class="float-right">{{ article.timestamp }}</span>
</small>
</blockquote>
</div>
{% endfor %}
<nav aria-label="Page navigation example" class="m-4">
<ul class="pagination justify-content-center">
<li class="page-item {% if not articles.has_prev %}disabled{% endif %}">
<a class="page-link" href="{{ url_for('blog.category', page=articles.prev_num,category_id=category_id) }}">上一页</a>
</li>
{% for page in articles.iter_pages(1,1,3,2) %}
{% if page %}
<li class="page-item {%if page==articles.page%}active{%endif%}">
<a class="page-link" href="{{ url_for('blog.category',page=page,category_id=category_id) }}">{{page}}</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#">…</a>
</li>
{% endif %}
{% endfor %}
<li class="page-item {% if not articles.has_next %}disabled{% endif %}">
<a class="page-link" href="{{ url_for('blog.category',page=articles.next_num,category_id=category_id) }}">下一页</a>
</li>
</ul>
</nav>
</div>
{% endblock %}
整个博客网站的效果如下所示:
首页:
![](https://img2020.cnblogs.com/blog/1709480/202009/1709480-20200928141240949-144918999.png)
分类页:
![](https://img2020.cnblogs.com/blog/1709480/202009/1709480-20200928150809481-84493178.png)
文章详情页:
![](https://img2020.cnblogs.com/blog/1709480/202009/1709480-20200928150839002-160998129.png)