Flask学习笔记-(八)分页功能实现

分页实现

1. 发布用户帖子

1.1. 新建用户帖子表单类

​ 修改app/forms.py脚本,新增用户帖子表单类,用于帖子信息的提交。

class PostForm(FlaskForm):
    """帖子提交表单"""
    post = TextAreaField('内容', validators=[DataRequired(), Length(min=1, max=140)])
    submit = SubmitField('提交')

1.2. 将帖子表单添加到首页模板中

​ 修改app/templates/index/index.html文件,增加帖子提交表单。

{% extends 'base.html' %}

{% block content %}
    <h1>Hi, {{ current_user.username }}!</h1>
    <form action="" method="post">
        {{ form.hidden_tag() }}
        <p>
            {{ form.post.label }}<br>
            {{ form.post(cols=32, rows=4) }}<br>
            {% for error in form.post.errors %}
                <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>{{ form.submit() }}</p>
    </form>
    {% for post in posts %}
        {% include 'common/post.html' %}
    {% endfor %}
{% endblock %}

1.3. 视图函数处理表单数据

​ 修改app/index.py脚本,修改原视图函数处理,增加表单数据的提交及查询展示。其中通过followed_posts方法可以获取本人以及其关注者对应的帖子信息。

from flask.views import View
from flask import render_template, flash, redirect, url_for
from flask_login import login_required, current_user

from app import db
from app.forms import PostForm
from app.models import Post


class IndexView(View):
    methods = ['GET', 'POST']
    decorators = [login_required]

    def dispatch_request(self):
        form = PostForm()
        if form.validate_on_submit():
            post = Post(body=form.post.data, author=current_user)
            db.session.add(post)
            db.session.commit()
            flash('你的帖子已提交!')
            return redirect(url_for('index'))

        # 获取本人及关注者对应的帖子信息
        posts = current_user.followed_posts().all()
        return render_template('index/index.html', title='首页', form=form, posts=posts)

1.4. 启动服务测试

​ 通过john用户登录首页。

在这里插入图片描述

​ 发表一篇帖子信息。

在这里插入图片描述

2. 新增发现页面展示所有用户的帖子

2.1. 新增发现视图函数

​ 修改app/index.py脚本,增加发现视图函数。

class ExploreView(View):
    """发现视图"""
    methods = ['GET']
    decorators = [login_required]

    def dispatch_request(self):
        posts = Post.query.order_by(Post.timestamp.desc()).all()
        return render_template('index/index.html', title='发现', posts=posts)

2.2. 注册发现视图

​ 修改app/__init__.py脚本,增加发现视图注册。

def create_app(test_config=None):
......
    # 注册Index首页视图URL
    from app.index import IndexView, ExploreView
    application.add_url_rule('/', view_func=IndexView.as_view('index'))
    # 注册Explore发现视图URL
    application.add_url_rule('/explore', view_func=ExploreView.as_view('explore'))
......

2.3.首页增加是否传入表单判断

​ 修改app/templates/index/index.html文件,增加表单是否传入判断,若未传入表单,则不展示帖子表单提交处理。

{% extends 'base.html' %}

{% block content %}
    <h1>Hi, {{ current_user.username }}!</h1>
    {% if form %}
        <form action="" method="post">
......
        </form>
    {% endif %}
......

2.4. base页面增加发现页面链接

​ 修改app/templates/base.html文件,增减发现页面链接。

......
<body>
    <div>
        博客:
        <a href="{{ url_for('index') }}">首页</a>
        <a href="{{ url_for('explore') }}">发现</a>
......

2.3. 将帖子子模板中作者信息修改为链接

​ 修改app/templates/common/post.html文件,将作者用户名修改为链接方式。

    <table>
        <tr valign="top">
            <td><img src="{{ get_avatars(post.author.email, 36) }}"></td>
            <td>
                <a href="{{ url_for('user.user_info', username=post.author.username) }}">
                    {{ post.author.username }}
                </a> 
                says:<br>{{ post.body }}
            </td>
        </tr>
    </table>

2.4. 启动服务测试

​ 通过用户john登录。

在这里插入图片描述

​ 通过用户susan登录,并新增帖子。

在这里插入图片描述

在这里插入图片描述

​ 点击发现链接。

在这里插入图片描述

​ 点击用户john的用户名链接。

在这里插入图片描述

3. 用户帖子分页处理

3.1. 给主页及发现页视图函数增加分页处理

​ 修改app/index.py脚本,增加分页处理。其中,查询页数通过参数page以查询字符串参数方式指定,该参数可以通过request.args对象获取,默认为第一页。

分页处理函数paginate

  • 第一个参数为当前查询页码数
  • 第二个参数为每页查询数据条数(设置到config.py文件中,测试先设置为2条)
  • 第三个参数为错误处理布尔标记,如果是True,当请求范围超出已知范围时自动引发404错误;如果是False,则会返回一个空列表
class IndexView(View):
    methods = ['GET', 'POST']
    decorators = [login_required]

    def dispatch_request(self):
......
        # 获取本人及关注者对应的帖子信息
        page = request.args.get('page', 1, type=int)
        # 分页处理
        posts = current_user.followed_posts().paginate(page, current_app.config['POSTS_PER_PAGE'], False)
        return render_template('index/index.html', title='首页', form=form, posts=posts)
    
    
class ExploreView(View):
    """发现视图"""
    methods = ['GET']
    decorators = [login_required]

    def dispatch_request(self):
        page = request.args.get('page', 1, type=int)
        # 分页处理
        posts = Post.query.order_by(Post.timestamp.desc()).paginate(page, current_app.config['POSTS_PER_PAGE'], False)
        return render_template('index/index.html', title='发现', posts=posts)

3.2. 新增分页导航视图

paginate方法返回一个Pagination的实例,该实例有几个属性可以用来构建分页链接:

  • items:请求内容的数据列表

  • has_next: 当前页之后存在后续页面时为真

  • has_prev: 当前页之前存在前置页面时为真

  • next_num: 下一页的页码

  • prev_num: 上一页的页码

    通过这几个元素,修改app/index.py脚本,可以生成上一页和下一页的链接并将其传入模板以渲染。url_for()函数有一个特点,可以添加任何关键字参数,如果这些参数的名字没有直接在URL中匹配使用,那么Flask将它们设置为URL的查询字符串参数。

class IndexView(View):
    methods = ['GET', 'POST']
    decorators = [login_required]

    def dispatch_request(self):
......
        # 获取本人及关注者对应的帖子信息
        page = request.args.get('page', 1, type=int)
        # 分页处理
        posts = current_user.followed_posts().paginate(page, current_app.config['POSTS_PER_PAGE'], False)
        # 下一页
        next_url = url_for('index', page=posts.next_num) if posts.has_next else None
        # 上一页
        prev_url = url_for('index', page=posts.prev_num) if posts.has_prev else None
        return render_template('index/index.html', title='首页', form=form, posts=posts.items,
                               next_url=next_url, prev_url=prev_url, page=page)
    
    
class ExploreView(View):
    """发现视图"""
    methods = ['GET']
    decorators = [login_required]

    def dispatch_request(self):
        page = request.args.get('page', 1, type=int)
        # 分页处理
        posts = Post.query.order_by(Post.timestamp.desc()).paginate(page, current_app.config['POSTS_PER_PAGE'], False)
        # 下一页
        next_url = url_for('explore', page=posts.next_num) if posts.has_next else None
        # 上一页
        prev_url = url_for('explore', page=posts.prev_num) if posts.has_prev else None
        return render_template('index/index.html', title='发现', posts=posts.items,
                               next_url=next_url, prev_url=prev_url, page=page)

3.3. 新增分页导航模板

​ 修改app/templates/index/index.html文件,增加分页导航展示。

......
    {% for post in posts %}
        {% include 'common/post.html' %}
    {% endfor %}
    <p>
        {% if prev_url %}
            <a href="{{ prev_url }}">上一页</a>
        {% endif %}
        &nbsp;第{{ page }}页&nbsp;
        {% if next_url %}
            <a href="{{ next_url }}">下一页</a>
        {% endif %}
    </p>
{% endblock %}

3.4. 启动服务测试

​ 通过用户susan登录,该用户有两条帖子,只展示当前页数。

在这里插入图片描述

​ 点击发现链接,展示所有用户的帖子信息,总共有三条,则会展示下一页链接。

在这里插入图片描述

​ 点击下一页链接,展示另外一条帖子信息,并显示上一页链接。

在这里插入图片描述

在这里插入图片描述

4. 个人主页分页处理

4.1. 视图函数增加分页处理

​ 修改app/user.py脚本,增加分页处理。

class UserInfoView(View):
    """用户信息查询"""
    methods = ['GET']
    decorators = [login_required]

    def dispatch_request(self, username):
        user = User.query.filter_by(username=username).first_or_404()
        page = request.args.get('page', 1, type=int)
        posts = user.posts.order_by(Post.timestamp.desc()).paginate(page, current_app.config['POSTS_PER_PAGE'], False)
        next_url = url_for('user.user_info', username=user.username, page=posts.next_num) if posts.has_next else None
        prev_url = url_for('user.user_info', username=user.username, page=posts.prev_num) if posts.has_prev else None
        return render_template('user/user_info.html', user=user, posts=posts.items,
                               next_url=next_url, prev_url=prev_url, page=page)

4.2. 模板添加分页导航

​ 修改app/templates/user/user_info.html文件,增减分页导航链接。

......
	<hr>
    {% for post in posts %}
        {% include 'common/post.html' %}
    {% endfor %}
    <p>
        {% if prev_url %}
            <a href="{{ prev_url }}">上一页</a>
        {% endif %}
        &nbsp;第{{ page }}页&nbsp;
        {% if next_url %}
            <a href="{{ next_url }}">下一页</a>
        {% endif %}
    </p>
{% endblock %}

4.3. 启动服务测试

​ 通过用户susan登录并新增一条帖子。

在这里插入图片描述

​ 点击个人资料链接,也会有分页处理。

在这里插入图片描述

在这里插入图片描述

5. 调整分页时每页数据条数参数

​ 修改app/config.py脚本,将条数调整为每页20条。

# -----------分页参数配置-------------#
# 每页展示数据条数
POSTS_PER_PAGE = 20
  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
STM32是一款非常流行的嵌入式微控制器系列,它具有强大的性能和丰富的外设资源。在学习STM32时,掌握如何进行Flash读写是非常重要的。 Flash是一种非易失性存储器,可以用来存储程序代码和数据。在STM32中,Flash存储器通常用来存储应用程序代码。下面是一个简单的Flash读写程序的示例: 1.首先,我们需要包含适用于所使用的STM32型号的头文件。例如,对于STM32F4系列,我们需要包含"stm32f4xx.h"。 2.然后,我们需要定义一个指向Flash存储器的指针变量。例如,可以使用如下代码:`uint32_t* flash_address = (uint32_t*)0x08000000;`其中0x08000000是Flash存储器的起始地址。 3.要读取Flash存储器中的数据,我们可以通过以下代码实现:`data = *flash_address;`其中data是一个变量,用于存储读取到的数据。 4.要写入数据到Flash存储器中,我们可以通过以下代码实现:`*flash_address = data;`其中data是要写入的数据。 需要注意的是,STM32的Flash存储器是有写保护机制的,因此在写入数据之前,我们需要禁用写保护。可以使用以下代码禁用写保护:`FLASH->KEYR = 0x45670123; FLASH->KEYR = 0xCDEF89AB;`然后才能进行数据写入。 另外,为了确保数据的完整性,我们可以使用CRC校验来验证Flash存储器中的程序代码的正确性。可以使用库函数来计算校验和,然后将其与预期的校验和进行比较以进行验证。 综上所述,掌握STM32的Flash读写操作对于嵌入式系统的开发非常重要。上述示例代码可以帮助我们快速进行Flash读写操作,同时注意写保护和数据校验可以提高数据的安全性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值