wtforms+flask_sqlalchemy在flask-admin视图下实现日期的修改与更新

背景:

在flask-admin 的modelview视图下实现自定义视图的表单修改/编辑是件不太那么容易的事情,特别是想不自定义前端view的情况下。

材料:

wtforms+flask_sqlalchemy

制作:

上代码

1、模型代码

from .exts import db
from flask_login import UserMixin
from datetime import datetimeclass AiConfig(db.Model, UserMixin):__tablename__ = 'ai_config'id = db.Column(db.Integer, primary_key=True, autoincrement=True)created_at = db.Column(db.TIMESTAMP, default=datetime.utcnow)updated_at = db.Column(db.TIMESTAMP, default=datetime.utcnow)status = db.Column(db.Integer)ai_name = db.Column(db.String(128))

注:默认日期函数可以采用 default=datetime.utcnow 来实现

2、视图测代码

a、AiConfigForm 表单

class AiConfigForm(form.Form):def get_countries():return Organ.query.order_by('updated_at').all()ai_name = fields.StringField('AI名称', validators=[validators.DataRequired()])ai_code = fields.StringField('AI编号', validators=[validators.DataRequired()])ai_extends = fields.TextAreaField('配置扩展', widget=TextArea())root_url = fields.URLField('根URL', validators=[validators.DataRequired()], widget=URLInput())organ = QuerySelectField('机构名称', validators=[validators.DataRequired()], query_factory=get_countries, get_label='org_name')  description = fields.TextAreaField('描述', widget=TextArea())status = fields.SelectField('状态', choices=[(1, '有效'), (0, '无效')], default=0)

b、modeview视图下实现表单新增

   @expose('/new/', methods=('GET', 'POST'))def create_view(self):bean = AiConfig()bean.updated_at = datetime.today()form = AiConfigForm(request.form, obj=bean)if self.validate_form(form):model = self.create_model(form)if model:flash(gettext('Record was successfully created.'), 'success')return redirect(self.get_save_return_url(model, is_created=True))if self.create_modal and request.args.get('modal'):template = self.create_modal_templateelse:template = self.create_templatereturn self.render(template, form=form)

注:上面代码片段中这样修改update_at 是不生效的,目前尚未找到在这个代码交互中修改表单AiConfigForm 中并未定义字段update_at 属性的方法 (因为属性赋值是在其self.create_model()内置函数中实现的)

c、modelview 视图下实现表单修改

    @expose('/edit/', methods=('GET', 'POST'))def edit_view(self):id = request.args['id']return_url = request.values.get('url') or self.get_url('.index_view')model = self.get_one(id)if model is None:flash(gettext('Record does not exist.'), 'error')return redirect(return_url)form = AiConfigForm(request.form, obj=model)if self.validate_form(form):model.updated_at = datetime.today()if self.update_model(form, model):flash(gettext('Record was successfully saved.'), 'success')# save buttonreturn redirect(self.get_save_return_url(model, is_created=False))   if request.method == 'GET' or form.errors:self.on_form_prefill(form, id)if self.edit_modal and request.args.get('modal'):template = self.edit_modal_templateelse:template = self.edit_templatereturn self.render(template, form=form)

注:上述代码片段中 model.updated_at = datetime.today() 是有效的,因为在self.update_model(form,model) 内置函数中只是将form 中表单数据通过 form.populate_obj(model) 值cp 的方式简单覆盖来实现,我们只需要在调用该方法前将model 进行修改便可生效。

效果 

1、编辑/新增 view中不存在日期2 

 

2、数据库中存在日期

3、列表中该记录存在日期

 

注:这就充分说明通过上述逻辑实现了新增日期和修改日期的后台修改

疑问与经验 

疑问

1、为啥不在AiConfigForm 表单中通过影藏字段来实现日期呢?

该方案有尝试,但是不行,因为数据库属性是日期类型的,实体中该字段也是日期类型,如果只是在表单中采用影藏字段,新增时非常好用,只需要通过form.updated_at.data=datetime.today()实现赋值,但编辑时就会因为模型字段与表单中针对updated_at 字段的类型定义不一致导致无法通过populate_obj 函数进行模型值赋值导致报异常,同时由于此刻表单中并没有updated_at这样的日期类型字段,有的只是影藏字段,故无法form.updated_at.data=datetime.today() 实现赋值。当然如果不怕麻烦可以写2个form 视图就可以友好结果上述问题。

2、为啥不直接自定义view模板呢?

当然可以,只是因为懒。

3、为啥不建2个AiConfigForm 视图,一个用于编辑一个用于新增?

当然可以,而且可以做到很优雅,只是懒

经验

1、在ModelView 的子视图中重写部分方法,如@expose('/new/', methods=('GET', 'POST'))和@expose('/edit/', methods=('GET', 'POST')),中如果采用wtforms 自定义表单,但又不想自定义表单视图,那么只需要简单的通过form = AiConfigForm(request.form, obj=bean) 方法在上面新增、编辑函数中使用wtforms 表单。但这里要说明的是AiConfigForm(request.form, obj=bean) 中的 obj 对象接收的是模型,通过把模型赋值给obj 的方式实现已有数据的回填,该方案在编辑中非常有用

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/63717.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【AIGC-ChatGPT进阶副业提示词】末日生存指南 2.0:疯狂科学家的荒诞智慧

引言 在这个不断变化的世界中,末日似乎总是lurking在角落。但是,亲爱的幸存者们,不要害怕!因为我,疯狂科学家2099,正在这里为你们带来最新版本的末日生存指南。这不是你祖母的应急手册,而是一本…

BiLSTM:深度学习中的双向长短期记忆网络

目录 ​编辑 1. BiLSTM原理 2. BiLSTM的应用案例 3. BiLSTM研究进展 4. BiLSTM技术挑战 5. BiLSTM未来趋势 6. BiLSTM的实际应用示例 6.1 数据准备 6.2 构建BiLSTM模型 6.3 训练模型 6.4 评估模型 6.5 可视化训练过程 7. 结论 在深度学习的浪潮中,BiLS…

RK3588 , mpp硬编码yuv, 保存MP4视频文件.

RK3588 , mpp硬编码yuv, 保存MP4视频文件. ⚡️ 传送 ➡️ Ubuntu x64 架构, 交叉编译aarch64 FFmpeg mppRK3588, FFmpeg 拉流 RTSP, mpp 硬解码转RGBRk3588 FFmpeg 拉流 RTSP, 硬解码转RGBRK3588 , mpp硬编码yuv, 保存MP4视频文件.

powershell美化

powershell美化 写在前面 除了安装命令,其他都是测试命令,后续再写进配置文件 安装主题控件 安装主题oh-my-posh,powershell中执行 winget install JanDeDobbeleer.OhMyPosh -s winget oh-my-posh init pwsh | Invoke-Expression # 查看…

2024/12/22周报

文章目录 摘要Abstract深度学习文献阅读1. 背景与问题2. 发明目的3. 方法与实现3.1 数据采集与变量选取3.2 BP神经网络建立稳态预测模型3.3 构建多目标优化函数3.4 多目标差分进化算法求解优化3.5 最优决策变量筛选3.6 实时控制 4. 系统实现5. 实际效果与验证5.1 仿真验证5.2 神…

前端编程训练 异步编程篇 请求接口 vue与react中的异步

文章目录 前言代码执行顺序的几个关键点接口请求vue与react中的异步 vue中的异步react的state修改异步 前言 本文是B站三十的前端课的笔记前端编程训练,异步编程篇 代码执行顺序的几个关键点 我们可以理解为代码就是一行一行,一句一句是执行(定义变…

C++-----函数与库

数学中的函数与编程中的函数对比 数学中的函数 - 数学函数是一种映射关系,例如,函数\(y f(x)x^{2}\),对于每一个输入值\(x\),都有唯一确定的输出值\(y\)。它侧重于描述变量之间的数量关系,通常通过公式来表示这种关系…

Loki 微服务模式组件介绍

目录 一、简介 二、架构图 三、组件介绍 Distributor(分发器) Ingester(存储器) Querier(查询器) Query Frontend(查询前端) Index Gateway(索引网关&#xff09…

C++ OpenGL学习笔记(1、Hello World空窗口程序)

终于抽出时间系统学习OpenGL 教程,同时也一步一步记录怎样利用openGL进行加速计算。 目录 1、环境准备1.1、库的下载1.2、库的选择及安装 2、OpenGL第一个项目,Hello World!2.1、新建hello world控制台项目2.2、配置openGL环境2.2.1 包含目录配置2.2.2 …

Linux系统命令基础

Linux命令⾏ [pypylinux ~]$ 普通⽤户py,登陆后 [rootpylinux ~]# 超级⽤户root,登录后root代表当前登录的⽤户 分隔符pylinux 主机名~ 当前的登录的位置,此时是家⽬录# 超级⽤户身份提示符 $ 普通⽤户身份提示符操作系统⽬录分隔符 Linux目录…

不同版本的 Redis 的键值对内存占用情况示例

不同版本的 Redis 的键值对内存占用情况示例 文章目录 不同版本的 Redis 的键值对内存占用情况示例Redis 6.0redisObjectdictEntrysds🍀 数据结构🍀 sdslen() 函数🍀 sdsReqType() 函数🍀 sdsHdrSize() 函数 内存分配 - malloc() …

实现 WebSocket 接入文心一言

目录 什么是 WebSocket? 为什么需要 WebSocket? HTTP 的局限性 WebSocket 的优势 总结:HTTP 和 WebSocket 的区别 WebSocket 的劣势 WebSocket 常见应用场景 WebSocket 握手过程 WebSocket 事件处理和生命周期 WebSocket 心跳机制 …

2024.7 XAI 遇见 LLM:可解释 AI 与大型语言模型之间关系的调查

https://arxiv.org/pdf/2407.15248 问题 Q1:XAI 技术当前如何与 LLMs 集成?Q2:将 LLMs 与 XAI 方法融合的新兴趋势是什么?Q3:当前相关文献存在哪些差距,哪些领域需要进一步研究? 挑战 LLMs …

RIP实验

要求及分析 路由器上分别配置环回 连接路由器的线路网段为12.1.1.0/24、23.1.1.1.0/24 R1和R3连接的网络地址分别为192.168.1.0/24/192.168.2.0/24 整个网络使用RIP达到全网可达 配置 先配置路由器各接口ip和环回和pc ip网关掩码(图略) 进行 RI…

Oracle 中间件 Webcenter Portal服务器环境搭建

环境信息 服务器基本信息 如下表,本次安装总共使用2台服务器,具体信息如下: Webcenter1服务器 归类 SOA服务器 Ip Address 172.xx.xx.xx.xx HostName wcc01.xxxxxx.com Alias wccprd01 Webcenter2服务器 归类 OSB服务器 Ip Addr…

macOS 配置 vscode 命令行启动

打开 vscode 使用 cmd shift p 组合快捷键,输入 install 点击 Install ‘code’ command in PATH Ref https://code.visualstudio.com/docs/setup/mac

分层架构 IM 系统之多媒体功能设计与实现

现在 IM 系统已经不仅限于文本消息的通讯了,多媒体数据占据越来越多的比重,比如:文件传输、语音通话、视频通话等。 在前面的文章(《基于需求分析模型来结构化剖析 IM 系统》)中我们分析过,“多媒体消息”…

0.gitlab ubuntu20.04 部署问题解决

安装依赖: ① sudo apt-get update 出现: 解决方式: 去 /etc/apt/sources.list.d 这个目录删除或注释对应的list文件 第三方软件的源一般都以list文件的方式放在 /etc/apt/sources.list.d 这个目录 重新运行sudo apt-get update 安装…

Next.js v15 - 服务器操作以及调用原理

约定 服务器操作是在服务器上执行的异步函数。它们可以在服务器组件和客户端组件中调用,用于处理 Next.js 应用程序中的表单提交和数据修改。 服务器操作可以通过 React 的 “use server” 指令定义。你可以将该指令放在 async 函数的顶部以将该函数标记为服务器操…

什么是3DEXPERIENCE SOLIDWORKS,它有哪些角色和功能?

将业界领先的 SOLIDWORKS 3D CAD 解决方案连接到基于单一云端产品开发环境 3DEXPERIENCE 平台。您的团队、数据和流程全部连接到一个平台进行高效的协作工作,从而能快速的做出更好的决策。 目 录: ★ 1 什么是3DEXPERIENCE SOLIDWORKS ★ 2 3DEXPERIE…