【问题标题】:Flask-Admin ModelView custom validation?Flask-Admin ModelView 自定义验证?
【发布时间】:2014-05-21 17:48:51
【问题描述】:

我正在研究结合 PeeWee 后端 ModelView 的 Flask-Admin(但我的问题也可能适用于 SQLAlchemy 后端),在文档或示例中我找不到两件事:

(1)。当我的模型有一个唯一字段并且我测试/尝试复制它时,我会看到一个默认的 Flask 崩溃屏幕,并显示消息:“IntegrityError: column username is not unique”

我正在测试 https://github.com/mrjoes/flask-admin/blob/master/examples/peewee/simple.py 中提供的 PeeWee 示例,并将第 21 行更改为“username = peewee.CharField(max_length=80, unique=True)”

然后我尝试使用“username”=“user1”添加两个用户。

是否有礼貌的方式返回编辑屏幕(甚至是列表屏幕,任何管理屏幕都会这样做)但带有受控的错误消息?我不需要自定义错误消息,当前消息正常(IntegrityError:列用户名不是唯一的)。但我不想要崩溃屏幕。

我可以设置/使用 Flask 的默认 500 页面,但是我会完全退出 Flask-Admin 流程,用户会“错过”他刚刚输入的数据。

我想回到编辑屏幕,但有一些警告/错误消息。我不介意必须扩展模板,这不是问题。但是我找不到一个地方来拦截错误并正确处理它。有什么建议吗?

和(2):

我还需要一种在流程中添加一些保存前验证的方法。例如,我处于具有 initial_date 和 final_date 的实体的编辑表单中,我想在保存之前确保 final_date 大于 initial_date 或为空。

我可以通过 javascript 在客户端执行此操作,扩展该实体的编辑模板并在尾部添加我的验证脚本(并拦截 form.submit 事件)。

但是如果我的验证需要一些服务器端的最后一分钟验证怎么办?有什么方法/地方可以拦截流程并添加我的验证,并且幸运的是,以问题 1 中讨论的相同方式返回我的错误消息?

提前致谢,

问候,

【问题讨论】:

  • 崩溃的原因 - 当 Flask 在调试模式下运行时,Flask-Admin 将重新抛出所有异常(甚至是 IntegrityError)。我将添加 IntegrityError 处理作为此规则的例外。可以在表单或on_model_change 中完成预保存 - 您可以从那里抛出异常。虽然 Werkzeug 调试器会显示异常,但在生产模式下,您会看到很好的错误消息。
  • @Joes on_model_change 是文档中所述的保存后挂钩":"在创建或更新模型之后执行一些操作。在 Flask admin AFAIK 中保存钩子。因此,扩展基表单类和子类中的自定义是回答 OP 问题的唯一方法。
  • @Devy on_model_change 在使用表单数据更新模型时调用,但在会话提交到数据库之前。因此,在那里抛出异常会阻止应用任何更改。

标签: python validation flask-admin flask-peewee


【解决方案1】:

我想我找到了一些有用的东西,但没有完全回答我的问题。

我在 PasteBin 上发布了一个示例:http://pastebin.com/siwiaJAw

首先,我找不到“保存前”步骤,但我找到了如何添加字段级自定义验证,这有助于创建和更新。

如果您查看示例,您会看到我添加的第 37-39 和 42-44 行:

def no_root_allowed(form, field):
    if field.data == 'root':
        raise ValidationError('"root" is not allowed')

form_args = dict(
    username=dict(validators=[no_root_allowed])
)

此验证器接收“表单”和“字段”,因此我可以进行涉及多个字段的验证(例如开始日期

所以,这解决了创建/编辑验证。如果验证器失败,Flask-Admin 会将我带回已经填充的编辑表单。不错!

但是删除有问题。如果我不想删除特定对象,我可以将其标记为 can_delete = False,但这会阻止删除任何实例。

我能找到的最好方法是拦截 delete_model 方法(第 55 行)并在预删除验证失败的情况下返回 False。但这不会引发任何信息,只会让我回到表格中。我无法向用户发送他无法删除该特定实例的消息。

我会继续学习,并会发布任何进一步的消息。

谢谢!

【讨论】:

  • 感谢 TON 发布此内容。节省了我大量挖掘的时间。
  • 您知道自定义验证器是否可以判断它是更新现有模型还是创建新模型? is_created 属性之类的东西?
  • 您可以使用flash('delete not allowed') 通知用户删除不可用。 from flask import flash
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-18
  • 1970-01-01
  • 1970-01-01
  • 2014-09-08
  • 1970-01-01
  • 1970-01-01
  • 2021-10-13
相关资源
最近更新 更多