Flask(四):flask分页+表单插件+form表单校验

分页

django 中使用封装好的分页器进行分页

提供了: page()

page_number

page_range 生成器 1,20

下一页 上一页 是否有上一页 是否有下一页

flask 自己封装分页器

封装了分页器

# Paginator(data,10)     将data数据进行分页,  每页10条
class Pager:
    """
    flask通过limit   offset 对数据进行分页

    切片
    提供的功能
    """
    #### params = User.query
    ###  data =  列表
    def __init__(self,data,page_size):
        """

        :param data:   数据
        :param page_size:     每页的条数
        """
        self.data = data   ### 数据
        self.page_size = page_size    ### 每页条数
        self.is_start = False
        self.is_end = False
        self.page_count = len(data)    ##  总条数
        self.previous_page = 0     ####上一页
        self.next_page = 0    ##### 下一页
        self.page_number = self.page_count / self.page_size  ### 总共的页数    len(data) / page_size
        if self.page_number == int(self.page_number):
            self.page_number = int(self.page_number)
        else:
            self.page_number = int(self.page_number) + 1
        self.page_range =( x for x in range(1,self.page_number + 1))  ## 迭代器   1 2 3 4 5 6 7 8 9 10

    def page_data(self,page):
        """
        page   offset   limit   每页10条
        1         0       10
        2        10       10
        切片      start     end
        1         0        10         (page-1)* 10
        2         10        20
        3         20        30
        :return:  返回分页的数据
        """
        # result = self.data.offset().limit().all()
        page_start = (page -1) * self.page_size### 切片开始的位置
        page_end = page * self.page_size    ## 切片结束的位置
        result = self.data[page_start:page_end]
        print (page)
        if page == 1:
            print ("--------------")
            self.is_start = True
        if page == self.page_number:
            self.is_end = True
        self.next_page = page + 1  ## 下一页
        self.previous_page = page - 1  ##上一页
        return result

表单插件 flask-wtf

django中学过csrf,django中间件 中已经写好了,flask中csrf嵌在表单后端校验(form表单类),叫flask-wtf

pip install flask-wtf
 

form表单

form表单类

  • 前端校验

    • 对页面上数据进行校验,校验的字符串的长度,类型,是否为空,

  • 后端校验

    • 校验用户是否存在,校验数据的(敏感字(admin))

1、定义form模型

2、视图返回实例对象

3、前端调用

{% extends "base.html" %}

{% block label %}
    任务发布
{% endblock %}
{% block content %}

    <p>
        {{ task.name.label }}:
        {{ task.name }}
    </p>
    <p>
    {{ task.description.label }}:
        {{ task.description }}
    </p>
    <p>
    {{ task.time.label }}:
        {{ task.time }}
    </p>
    <p>
    {{ task.public.label }}:
        {{ task.public }}
    </p>

{% endblock %}

form 表单 前端校验

常用的前端校验的规则

DataRequired不能为空
Email是否是邮箱格式
Equelto校验两个值是否心相同,常用于校验密码是否一样
length长度 max min
NumberRange数字范围
AnyOf指定范围
NoneOf不在范围

需要在视图中看到检验结果

自定义校验

定义规则

安装

 

<think>嗯,用户想实现一个带分页的数据库查询,前端表格展示,并且支持按开始时间、结束时间和设备编号进行过滤。首先,我得考虑后端怎么处理这些可选条件的分页查询。可能需要动态拼接SQL语句,根据用户是否提供了某个条件来添加对应的WHERE子句。比如,如果用户没有输入开始时间,那这个条件就不加到查询里。然后分页的话,后端需要接收页码和每页大小,计算偏移量。 接下来,前端需要有一个表格,比如使用Element UI的el-table组件,配合分页插件。用户可能需要在表格上方放置筛选表单,输入设备编号、选择开始和结束时间,然后点击查询按钮触发请求。分页切换的时候,也要能自动加载对应页的数据。 然后,前后端的数据交互格式要统一。后端返回的数据应该包括当前页的数据列表、总记录数,这样前端分页插件才能正确显示总页数。比如返回一个包含data和total的JSON对象。 还要考虑参数校验,比如开始时间不能晚于结束时间,设备编号的格式是否正确。后端在处理请求时,需要先验证这些参数的有效性,避免SQL注入或者无效查询。 另外,用户提到的引用中有提到flask分页器封装,可能可以参考如何在后端进行分页处理。比如使用SQL的LIMIT和OFFSET,或者ORM框架自带的分页方法,比如SQLAlchemy的paginate方法。这样后端可以更高效地处理分页逻辑。 前端部分,引用里提到了Vue和Element UI的表格导出,但用户的需求主要是分页和过滤。可能需要使用el-table和el-pagination组件,监听分页事件,当页码或每页大小变化时,重新请求数据。同时,筛选表单里的条件变化也要触发重新查询。 还有,用户的可选条件过滤,前端需要处理可能为空的情况,比如设备编号为空的话,就不发送这个参数到后端。时间选择器可能需要做格式转换,比如转成ISO格式或者时间戳,方便后端处理。 测试的时候,要注意边界情况,比如没有符合条件的记录时,后端返回空数组,前端显示无数据。分页参数超出范围时,后端如何处理,比如返回错误信息或者自动调整到最后一页。 最后,安全性方面,后端要对输入的参数进行过滤,防止SQL注入,尤其是设备编号这类用户输入的字段。使用预编译的SQL语句或者ORM框架可以有效避免这类问题。</think>### 分步实现方法 #### 一、后端实现(以Flask+SQLAlchemy为例) 1. **定义请求参数格式** 接收分页参数(页码`page`、每页数量`page_size`)和过滤条件(`start_time`、`end_time`、`device_id`): ```python from flask import request, jsonify from sqlalchemy import and_ @app.route('/query_data', methods=['GET']) def query_data(): page = request.args.get('page', 1, type=int) page_size = request.args.get('page_size', 10, type=int) start_time = request.args.get('start_time') end_time = request.args.get('end_time') device_id = request.args.get('device_id') ``` 2. **动态构建查询条件** 使用`SQLAlchemy`动态拼接过滤条件: ```python query = DeviceData.query # 假设模型为DeviceData filters = [] if start_time: filters.append(DeviceData.timestamp >= start_time) if end_time: filters.append(DeviceData.timestamp <= end_time) if device_id: filters.append(DeviceData.device_id == device_id) if filters: query = query.filter(and_(*filters)) ``` 3. **分页查询** 利用`paginate`方法实现分页: ```python pagination = query.paginate(page=page, per_page=page_size, error_out=False) result = { 'data': [item.to_dict() for item in pagination.items], # 假设模型有to_dict方法 'total': pagination.total } return jsonify(result) ``` #### 二、前端实现(以Vue+ElementUI为例) 1. **表格与分页组件** 使用`el-table`和`el-pagination`组件: ```html <el-table :data="tableData"> <el-table-column prop="device_id" label="设备编号"></el-table-column> <el-table-column prop="timestamp" label="时间"></el-table-column> </el-table> <el-pagination @current-change="handlePageChange" @size-change="handleSizeChange" :current-page="currentPage" :page-sizes="[10, 20, 50]" :page-size="pageSize" :total="total"> </el-pagination> ``` 2. **筛选表单与数据请求** 添加筛选表单并触发请求: ```html <el-form @submit.native.prevent="loadData"> <el-input v-model="filter.device_id" placeholder="设备编号"></el-input> <el-date-picker v-model="filter.start_time" type="datetime"></el-date-picker> <el-date-picker v-model="filter.end_time" type="datetime"></el-date-picker> <el-button type="primary" @click="loadData">查询</el-button> </el-form> ``` ```javascript methods: { async loadData() { const params = { page: this.currentPage, page_size: this.pageSize, device_id: this.filter.device_id, start_time: this.filter.start_time?.toISOString(), end_time: this.filter.end_time?.toISOString() } const res = await axios.get('/query_data', { params }) this.tableData = res.data.data this.total = res.data.total } } ``` #### 三、关键注意点 1. **时间格式处理** 前端需将日期对象转为ISO字符串或时间戳格式[^3] 2. **空值过滤** 后端应忽略未传递的过滤条件(如`device_id`为空时不参与筛选) 3. **性能优化** 数据库需对`device_id`和`timestamp`字段建立索引
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值