用 Flask 来写个轻博客 (14) — M(V)C_实现项目首页的模板-阿里云开发者社区

开发者社区> 范桂飓> 正文

用 Flask 来写个轻博客 (14) — M(V)C_实现项目首页的模板

简介: 目录 目录 前文列表 实现所需要的视图函数 实现 homehtml 模板 代码分析 实现效果 前文列表 用 Flask 来写个轻博客 (1) — 创建项目 用 Flask 来写个轻博客 (2) — Hello World! 用 Flask 来写个轻博客...
+关注继续查看

目录

前文列表

用 Flask 来写个轻博客 (1) — 创建项目
用 Flask 来写个轻博客 (2) — Hello World!
用 Flask 来写个轻博客 (3) — (M)VC_连接 MySQL 和 SQLAlchemy
用 Flask 来写个轻博客 (4) — (M)VC_创建数据模型和表
用 Flask 来写个轻博客 (5) — (M)VC_SQLAlchemy 的 CRUD 详解
用 Flask 来写个轻博客 (6) — (M)VC_models 的关系(one to many)
用 Flask 来写个轻博客 (7) — (M)VC_models 的关系(many to many)
用 Flask 来写个轻博客 (8) — (M)VC_Alembic 管理数据库结构的升级和降级
用 Flask 来写个轻博客 (9) — M(V)C_Jinja 语法基础快速概览
用 Flask 来写个轻博客 (10) — M(V)C_Jinja 常用过滤器与 Flask 特殊变量及方法
用 Flask 来写个轻博客 (11) — M(V)C_创建视图函数
用 Flask 来写个轻博客 (12) — M(V)C_编写和继承 Jinja 模板
用 Flask 来写个轻博客 (13) — M(V)C_WTForms 服务端表单检验

实现所需要的视图函数

  • 在开始实现首页模板之前, 我们为了调试和显示的方便, 首先伪造一些假数据:
    • fake_data.py
import random
import datetime
from uuid import uuid4

from models import db, User, Tag, Post

user = User(id=str(uuid4()), username='jmilkfan', password='fanguiju')
db.session.add(user)
db.session.commit()

user = db.session.query(User).first()
tag_one = Tag(id=str(uuid4()), name='Python')
tag_two = Tag(id=str(uuid4()), name='Flask')
tag_three = Tag(id=str(uuid4()), name='SQLALchemy')
tag_four = Tag(id=str(uuid4()), name='JMilkFan')
tag_list = [tag_one, tag_two, tag_three, tag_four]

s = "EXAMPLE TEXT"

for i in xrange(100):
    new_post = Post(id=str(uuid4()), title="Post" + str(i))
    new_post.user = user
    new_post.publish_date = datetime.datetime.now()
    new_post.text = s
    new_post.tags = random.sample(tag_list, random.randint(1, 3))
    db.session.add(new_post)

db.session.commit()

直接在 manager shell 中导入就能够执行该脚本文件:

>>> import fake_data

home.html 的视图函数之前博文中就已经记录过了,现在再将必须的视图函数代码贴出。

  • views.py
from flask import render_template
from sqlalchemy import func

from main import app
from models import db, User, Post, Tag, Comment, posts_tags


def sidebar_data():
    """Set the sidebar function."""

    # Get post of recent
    recent = db.session.query(Post).order_by(
            Post.publish_date.desc()
        ).limit(5).all()

    # Get the tags and sort by count of posts.
    top_tags = db.session.query(
            Tag, func.count(posts_tags.c.post_id).label('total')
        ).join(
            posts_tags
        ).group_by(Tag).order_by('total DESC').limit(5).all()
    return recent, top_tags


@app.route('/')
@app.route('/<int:page>')
def home(page=1):
    """View function for home page"""

    posts = Post.query.order_by(
        Post.publish_date.desc()
    ).paginate(page, 10)

    recent, top_tags = sidebar_data()

    return render_template('home.html',
                           posts=posts,
                           recent=recent,
                           top_tags=top_tags)

@app.route('/post/<string:post_id>')
def post(post_id):
    """View function for post page"""

    post = Post.query.get_or_404(post_id)
    tags = post.tags
    comments = post.comments.order_by(Comment.date.desc()).all()
    recent, top_tags = sidebar_data()

    return render_template('post.html',
                           post=post,
                           tags=tags,
                           comments=comments,
                           recent=recent,
                           top_tags=top_tags)


@app.route('/tag/<string:tag_name>')
def tag(tag_name):
    """View function for tag page"""

    # Tag.qurey() 对象才有 first_or_404(),而 db.session.query(Model) 是没有的
    tag = Tag.query.filter_by(name=tag_name).first_or_404()
    posts = tag.posts.order_by(Post.publish_date.desc()).all()
    recent, top_tags = sidebar_data()

    return render_template('tag.html',
                           tag=tag,
                           posts=posts,
                           recent=recent,
                           top_tags=top_tags)

实现 home.html 模板

  • templates/home.html
<!-- Replace the TITLE of template base.html -->
{% extends "base.html"%}
{% block title %}JmilkFan's Blog{% endblock %}

<!-- Replace the BODY of template base.html -->
{% block body %}
<!-- The data object from view function: `home()` -->
<div class="row">
  <div class="col-lg-9">
    <!-- Get Pagination object-->
    {% for post in posts.items %}
    <div class="row">
      <div class="col-lg-12">
        <h1>{{ post.title }}</h1>
      </div>
    </div>
    <div class="row">
      <div class="col-lg-12">
        {{ post.text | truncate(255) | safe }}
        <!-- Set the link for read more -->
        <a href="{{
          url_for('post', post_id=post.id)
          }}">Read More</a>
      </div>
    </div>
    {% endfor %}
  </div>
  <div class="col-lg-3">
    <div class="row">
      <h5>Recent Posts</h5>
      <ul>
        {% for post in recent %}
        <!-- Set the link for recent posts. -->
        <li><a href="{{
          url_for('post', post_id=post.id)
          }}">{{ post.title }}</a></li>
        {% endfor %}
      </ul>
    </div>
    <div class="row">
      <h5>Popular Tags</h5>
      <ul>
        {% for tag in top_tags %}
        <li><a href="{{
          url_for('tag', tag_name=tag[0].name)
          }}">{{ tag[0].name }}</a></li>
        {% endfor %}
      </ul>
    </div>
  </div>
  <!-- Call the Macro: `render_pagination` from base.html -->
  {{ render_pagination(posts, 'home') }}
</div>
{% endblock %}

代码分析

需求:我们希望当访问到域名 http://<ipaddress>:5000/,即访问博客的 / 时,能够正文处显示文章列表,右上侧边栏显示最新的 5 篇博文,右下侧边拦显示 关联博文数最多的 5 个标签,并且希望每一个页面的右侧边栏都是一致的。

  • 按照这个需求,首先我们需要定义一个路由函数(在这里同时也是视图函数) home() 来跳转到首页,并且首页中具有分页的功能,所以会定义两个 app.oute() 装饰器。

  • 同时因为我们需要在右侧边栏显示最新的 5 篇博文和博文关联数最多的 5 个标签,所以需要提供 recent/recent 数据对象,并且这些对象是高重用的,所以将其抽象成一个函数。

  • 我们还希望能够通过右侧边拦提供的链接跳转到具体的 post 或 tag 中,这就需要得到 posts/tags 表中的数据对象,所以会使用到视图函数 post()/tag()

实现效果

这里写图片描述

  • 再结合在前面博文中实现的分页链接宏
    这里写图片描述

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Flask入门模板过滤器与测试器(五)
1 模板引擎之过滤器 概念 : 过滤器本质上是个转换函数,第一个参数是待过滤的变量。如果它有第二个参数,模板中就必须传进去。
902 0
Cookiecutter通过项目模板创建项目
Cookiecutter通过项目模板创建项目
10 0
2014秋C++ 第12周项目 C++函数新特征与递归函数
课程主页在http://blog.csdn.net/sxhelijian/article/details/39152703,课程资源在云学堂“贺老师课堂”同步展示,使用的帐号请到课程主页中查看。  【项目1- 阅读程序】阅读下列程序,写出程序的运行结果。上机时运行程序,与你的预期进行对照、理解。如果对运行结果和其背后的原理仍不理解,请通过单步执行的手段跟踪理解。(1)阅读下面两个有静态局部变量
1133 0
SpringBoot项目使用Scala进行Web开发
本文介绍如何在Springboot中使用Scala进行web开发
2820 0
阿里云服务器ubuntu18.04 部署flask项目
由于之前的腾讯云服务器一年即将到期,续费非常昂贵,故趁在阿里云618活动低价入手了个3年的,感觉还不错。 本次博客服务器端环境搭建到项目部署是从崭新的aliyun服务器入手,登录账户为root。 特此记录一下过程。
359 0
Asp.net MVC3 企业网站系统高仿博客园 首页左侧列表页面 实现效果
在前一篇文章Asp.net MVC 3 开发企业网站系统仿照博客园部分功能--总体设计中介绍了数据库的总体设计,现在呢我们就来实现博客园的左侧网站分类效果实现。当然因为我的前端功底实在不敢恭维,所以我采用博客园的CSS和JS脚本,这样我们可以提高网站的实现速度,而不用为了前端的显示界面调整浪费时间(注:前端很重要)。
1144 0
ios项目常用模板框架之UITabBar+Nav
在实际的项目开发中总是有几个比较常见的模板,小编这几天给大伙出几期常用模板的博客,希望大家多提宝贵的意见! 这几个月最常用的莫过于Nav+UITabBar模板了;在实际的项目中,我比较侧重于纯代码,比较不喜欢拖控件,至于利弊在这里不多说了,言归正传。
677 0
项目交付为什么失败?-记我在某个项目中的迷思
上个项目接近尾声,我以developer的身份加入了现在的项目,姑且叫做项目A吧。说实话A项目蛮神奇的,干了一年多了只有一次release,8月初要进行第二次release了,但是测试环境还未搭建好。
828 0
C++项目参考解答-求最大公约数
【项目-求最大公约数】(1)输入两个数,并求出其最大公约数 #include &lt;iostream&gt; using namespace std; //自定义函数的原型(即函数声明) int main() { int a,b,g; cin&gt;&gt;a&gt;&gt;b; g=gcd(a,b); cout&lt;&lt;"最大公约数是: "&lt;&lt;g; re
880 0
+关注
范桂飓
OpenStack Developer, Opensource Lover :- )
263
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载