In my application, I have Users and Posts as models. Each post has a foreign key to a username. When I create a ModelView on top of my Posts model I can create posts as specific users in the admin interface as seen in the screenshot below
After I have added a post and click "Save and Add Another", the "User" reverts back to "user1". How can I make the form remember the previous value "user2"?
My reserach has led me to believe it can be done by modifying on_model_change and on_form_prefill, and saving the previous value in the flask session, but it seems to be overengineering such a simple task. There must be a simpler way.
My code can be seen below
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)
I have come across this situation before and i have solved it using 2 functions. its pretty easy and small.
@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
the above function will let you populate the values in html when user tries to edit any value. This can be populated using the value stored. And below is a function that helps you save the value from previous edit.
within this class MyModelView(sqla.ModelView):
you need to add the below 2 functions.
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
This is a 2 step operation that's pretty small and does not need a lot of time. I have added just a skeleton/pseudo code for now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With