У меня есть модель данных, которая имеет столбец, который зависит от других значений столбца, следуя инструкциям на этой странице. Я создал контекстно-зависимую функцию, которая используется для определения значения этого конкретного столбца при создании, примерно так:
def get_column_value_from_context(context):
# Instructions to produce value
return value
class MyModel(db.Model):
id = db.Column(db.Integer,
primary_key=True)
my_column = db.Column(db.String(64),
nullable=False,
default=get_column_value_from_context)
name = db.Column(db.String(32),
nullable=False,
unique=True,
index=True)
title = db.Column(db.String(128),
nullable=False)
description = db.Column(db.String(256),
nullable=False)
Этот подход работает довольно прилично, я могу создавать строки без проблем из командной строки или с помощью скрипта.
Я также добавил ModelView
в приложение с помощью Flask-Admin:
class MyModelView(ModelView):
can_view_details = True
can_set_page_size = True
can_export = True
admin.add_view(MyModelView(MyModel, db.session))
Это также работает довольно прилично, пока я не нажму кнопку " Создать" в представлении списка. Я получаю эту ошибку:
AttributeError: объект 'NoneType' не имеет атрибута 'get_current_parameters'
Поскольку реализация create_model
обработчика в ModelView
является это:
def create_model(self, form):
"""
Create model from form.
:param form:
Form instance
"""
try:
model = self.model()
form.populate_obj(model)
self.session.add(model)
self._on_model_change(form, model, True)
self.session.commit()
except Exception as ex:
if not self.handle_view_exception(ex):
flash(gettext('Failed to create record. %(error)s', error=str(ex)), 'error')
log.exception('Failed to create record.')
self.session.rollback()
return False
else:
self.after_model_change(form, model, True)
return model
и здесь нет context
при создании экземпляра модели. Итак, я создал пользовательский вид, в котором можно было бы переопределить экземпляр модели в обработчике создания:
class CustomSQLAView(ModelView):
def __init__(self, *args, **kwargs):
super(CustomSQLAView, self).__init__(*args, **kwargs)
def create_model(self, form):
"""
Create model from form.
:param form:
Form instance
"""
try:
model = self.get_populated_model(form)
self.session.add(model)
self._on_model_change(form, model, True)
self.session.commit()
except Exception as ex:
if not self.handle_view_exception(ex):
flash(gettext('Failed to create record. %(error)s', error=str(ex)), 'error')
log.exception('Failed to create record.')
self.session.rollback()
return False
else:
self.after_model_change(form, model, True)
return model
def get_populated_model(self, form):
model = self.model()
form.populate_obj(model)
return model
Теперь я могу переопределить метод get_populated_model
для создания экземпляра модели обычным способом:
class MyModelView(CustomSQLAView):
can_view_details = True
can_set_page_size = True
can_export = True
def get_populated_model(self, form):
model = self.model(
name=form.name.data,
title=form.title.data,
description=form.description.data,
)
return model
Несмотря на это, я подозреваю, что это что-то ломает. Колба-Admin имеет несколько реализации populate_obj
метода форм и полей, поэтому я хотел бы, чтобы держать все в безопасности.
Каков правильный способ сделать это?