Часто требуется на формах Flask.admin создавать виджеты поведение которых не предусмотренно стандарными моделями и для решения этой проблемы необходимо уметь создавать свои виджеты, путём наследования базовых и расширением их функционала
Например, мне в модели страницы необходимо указывать путь к шаблону с помощью которого будет генерироваться редактируемая страница, а список шаблонов получается путём сканирования директории шаблонов текущего домена (мультидоменная CMS), для решения этой проблемы наследую от wtforms.fields.SelectField новый класс SelectTemplateField у которого переопределяю конструктор, где инициализирую параметр choices для родительского класса
делается это вот так, в файле fields.py объявляю новый класс
class SelectTemplateField(SelectField):
def __init__(self, *args, **kwargs):
template_dir = os.path.join(kwargs['app_template'], g.domen.template_path)
choices = [ (name,name) for name in os.listdir(template_dir) if os.path.isfile(os.path.join(template_dir,name))]
choices.sort()
kwargs.pop('app_template')
kwargs['choices'] = choices
return super(SelectTemplateField, self).__init__(*args, **kwargs)
в конструкторе
- вычисляю путь к директории шаблонов текущего домена (template_dir)
- заполняю список именами файлов из этой директории
- сортирую список
- удаляю из kwargs элемент app_template, иначе базовый класс вылетит с ошибкой
- добавляю в отсортированный список с доступными шаблонами в kwargs
- вызываю конструктор базового класса
Затем этот виджен нужно подключить к классу PageAdmin, делается это путём добавления в класс PageAdmin опции form_extra_fields сделующим образом:
form_extra_fields = {
'template': SelectTemplateField(u'шаблон',
app_template = os.path.join(app.root_path, app.template_folder)),
}
Здесь определяется стандартный класс для свойства template у класса Page, путём переопределения для него виджета с его инициализацией свойств label и app_template (которое затем используется в конструкторе переопредённого класса)
Вот так легко и просто можно очень существенно расширить возможности генераторов форм во Flask