I am trying to create a slug field in one of my DB models. I am using Flask-SQLAlchemy and Flask-Admin. My Class is defined as:
class Merchant(db.Model):
__tablename__ = 'merchants'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String())
...
slug = db.Column(db.String())
def __repr__(self):
return 'Merchant: {}'.format(self.name)
I have attempted to implement something like this from this question:
def __init__(self, *args, **kwargs):
if not 'slug' in kwargs:
kwargs['slug'] = slugify(kwargs.get('name', ''))
super().__init__(*args, **kwargs)
However it does not work when I am creating the new Merchant using Flask-Admin.
In trying to determine why, I change the init function to simply print kwargs
. When I create a new Merchant in Flask-Admin, it prints {}
, however when I do it in the python shell, like Merchant(name ='test')
, it prints {'name' : 'test'}
.
Does anyone know how I can access the arguments being passed to my class at init from Flask-Admin?
It looks like Flask-Admin is not passing constructor arguments when initialising the new object and your code doesn't have any effect. I haven't checked the source code, but they could be doing something like:
m = Merchant()
...
m.name = 'foo'
I think your best bet if you want to continue using Flask-Admin would be extending the ModelView
and implementing the on_model_change
hook:
class MerchantModelView(BaseModelView):
def on_model_change(self, form, model, is_created):
if is_created and not model.slug:
model.slug = slugify(model.name)
You can fine more information in the documentation.