Flask 管理员记住表单值
Flask admin remember form value
在我的应用程序中,我将 Users 和 Posts 作为模型。每个 post 都有一个用户名的外键。当我在我的 Posts 模型之上创建一个 ModelView 时,我可以在管理界面中创建 posts 作为特定用户
如下面的屏幕截图所示
在我添加 post 并单击 "Save and Add Another" 后,"User" 恢复为 "user1"。如何让表单记住之前的值 "user2"?
我的研究让我相信它可以通过修改 on_model_change 和 on_form_prefill 并在 flask 会话中保存以前的值来完成,但似乎过度设计了这样一个简单的任务.一定有更简单的方法。
下面可以看到我的代码
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import flask_admin
from flask_admin.contrib import sqla
app = Flask(__name__)
db = SQLAlchemy()
admin = flask_admin.Admin(name='Test')
class Users(db.Model):
"""
Contains users of the database
"""
user_id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True, nullable=False)
def __str__(self):
return self.username
class Posts(db.Model):
"""
Contains users of the database
"""
post_id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(11), db.ForeignKey(Users.username), nullable=False)
post = db.Column(db.String(256))
user = db.relation(Users, backref='user')
def build_sample_db():
db.drop_all()
db.create_all()
data = {'user1': 'post1', 'user1': 'post2', 'user2': 'post1'}
for user, post in data.items():
u = Users(username=user)
p = Posts(username=user, post=post)
db.session.add(u)
db.session.add(p)
db.session.commit()
class MyModelView(sqla.ModelView):
pass
if __name__ == '__main__':
app.config['SECRET_KEY'] = '123456790'
app.config['DATABASE_FILE'] = 'sample_db.sqlite'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database'
app.config['SQLALCHEMY_ECHO'] = True
db.init_app(app)
admin.init_app(app)
admin.add_view(MyModelView(Posts, db.session))
with app.app_context():
build_sample_db()
# Start app
app.run(debug=True)
我以前遇到过这种情况,我用2个函数解决了它。它非常简单而且很小。
@expose('/edit/', methods=('GET', 'POST'))
def edit_view(self):
#write your logic to populate the value into html
self._template_args["arg_name"] = stored_value
# in your html find this value to populate it as you need
当用户尝试编辑任何值时,上述函数将允许您填充 html 中的值。这可以使用存储的值来填充。下面是一个功能,可以帮助您保存以前编辑的值。
在此 class MyModelView(sqla.ModelView):
中,您需要添加以下 2 个函数。
def on_model_change(self, form, model, is_created):
stored_value = model.user # this is your user name stored
# get the value of the column from your model and save it
这是一个非常小的 2 步操作,不需要很多时间。我现在只添加了 skeleton/pseudo 代码。
on_form_prefill 不会帮助您解决这个问题,因为它只适用于编辑表单。
As the lib code says -> on_form_prefill => Perform additional actions to
pre-fill the edit form
当请求命中时,会发生以下代码流:
(基础class) 视图(create_view) ->create_form->_create_form_class->get_create_form->get_form-> scaffold_form
因此,如果我们想要更改正在加载的创建表单的默认值,我们可以在处理表单的方法中更新它,如上述流程中所述。
因此我们可以覆盖create_form。
def create_form(self):
form = super().create_form()
# set the user id we want in the form as default.
form.user_id.default = 'USER_2_ID'
return form
这是为了获取表单的默认值。
要设置我们覆盖on_model_change
的值
def on_model_change(self, form, model, is_created):
# set the USER_ID from this model.user_id
pass
现在从 setter 和 getter 方法共享此数据 (USER_ID) 的方法如下,
- 我们在 cookie 中设置它并获得创建请求。
- 更新 "save and add another" 按钮 link 以在查询字符串中添加 user_id。
此数据必须在两个不同的请求之间共享,因此将其存储在应用程序上下文中,g 将不起作用。应用上下文"will not be shared between requests"
def create_form(self):
form = super().create_form()
user_id = request.args.get('user_id')
form.user_id.default = user_id
# or if you want only one option to be available
user_query = self.session.query(User).filter(User.id = user_id).one()
form.user.query = [user_query]
return form
如上回答提到使用edit_view、create_view,也可以用来加
An easy option but not a good one will be to query on creating
that will give you the last entry(But this approach is not optimal
one)
@expose('/new/', methods=('GET', 'POST'))
def create_view(self):
model = self.get_model()
# query the model here to get the latest value of the user_id
self._template_args['user_id'] = user_id
return super(YourAdmin, self).details_view()
在我的应用程序中,我将 Users 和 Posts 作为模型。每个 post 都有一个用户名的外键。当我在我的 Posts 模型之上创建一个 ModelView 时,我可以在管理界面中创建 posts 作为特定用户 如下面的屏幕截图所示
在我添加 post 并单击 "Save and Add Another" 后,"User" 恢复为 "user1"。如何让表单记住之前的值 "user2"?
我的研究让我相信它可以通过修改 on_model_change 和 on_form_prefill 并在 flask 会话中保存以前的值来完成,但似乎过度设计了这样一个简单的任务.一定有更简单的方法。
下面可以看到我的代码
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import flask_admin
from flask_admin.contrib import sqla
app = Flask(__name__)
db = SQLAlchemy()
admin = flask_admin.Admin(name='Test')
class Users(db.Model):
"""
Contains users of the database
"""
user_id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True, nullable=False)
def __str__(self):
return self.username
class Posts(db.Model):
"""
Contains users of the database
"""
post_id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(11), db.ForeignKey(Users.username), nullable=False)
post = db.Column(db.String(256))
user = db.relation(Users, backref='user')
def build_sample_db():
db.drop_all()
db.create_all()
data = {'user1': 'post1', 'user1': 'post2', 'user2': 'post1'}
for user, post in data.items():
u = Users(username=user)
p = Posts(username=user, post=post)
db.session.add(u)
db.session.add(p)
db.session.commit()
class MyModelView(sqla.ModelView):
pass
if __name__ == '__main__':
app.config['SECRET_KEY'] = '123456790'
app.config['DATABASE_FILE'] = 'sample_db.sqlite'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database'
app.config['SQLALCHEMY_ECHO'] = True
db.init_app(app)
admin.init_app(app)
admin.add_view(MyModelView(Posts, db.session))
with app.app_context():
build_sample_db()
# Start app
app.run(debug=True)
我以前遇到过这种情况,我用2个函数解决了它。它非常简单而且很小。
@expose('/edit/', methods=('GET', 'POST'))
def edit_view(self):
#write your logic to populate the value into html
self._template_args["arg_name"] = stored_value
# in your html find this value to populate it as you need
当用户尝试编辑任何值时,上述函数将允许您填充 html 中的值。这可以使用存储的值来填充。下面是一个功能,可以帮助您保存以前编辑的值。
在此 class MyModelView(sqla.ModelView):
中,您需要添加以下 2 个函数。
def on_model_change(self, form, model, is_created):
stored_value = model.user # this is your user name stored
# get the value of the column from your model and save it
这是一个非常小的 2 步操作,不需要很多时间。我现在只添加了 skeleton/pseudo 代码。
on_form_prefill 不会帮助您解决这个问题,因为它只适用于编辑表单。
As the lib code says -> on_form_prefill => Perform additional actions to pre-fill the edit form
当请求命中时,会发生以下代码流:
(基础class) 视图(create_view) ->create_form->_create_form_class->get_create_form->get_form-> scaffold_form
因此,如果我们想要更改正在加载的创建表单的默认值,我们可以在处理表单的方法中更新它,如上述流程中所述。
因此我们可以覆盖create_form。
def create_form(self):
form = super().create_form()
# set the user id we want in the form as default.
form.user_id.default = 'USER_2_ID'
return form
这是为了获取表单的默认值。
要设置我们覆盖on_model_change
的值def on_model_change(self, form, model, is_created):
# set the USER_ID from this model.user_id
pass
现在从 setter 和 getter 方法共享此数据 (USER_ID) 的方法如下,
- 我们在 cookie 中设置它并获得创建请求。
- 更新 "save and add another" 按钮 link 以在查询字符串中添加 user_id。
此数据必须在两个不同的请求之间共享,因此将其存储在应用程序上下文中,g 将不起作用。应用上下文"will not be shared between requests"
def create_form(self):
form = super().create_form()
user_id = request.args.get('user_id')
form.user_id.default = user_id
# or if you want only one option to be available
user_query = self.session.query(User).filter(User.id = user_id).one()
form.user.query = [user_query]
return form
如上回答提到使用edit_view、create_view,也可以用来加
An easy option but not a good one will be to query on creating that will give you the last entry(But this approach is not optimal one)
@expose('/new/', methods=('GET', 'POST'))
def create_view(self):
model = self.get_model()
# query the model here to get the latest value of the user_id
self._template_args['user_id'] = user_id
return super(YourAdmin, self).details_view()