Формы Flask.admin часто требуют создания виджетов, поведение которых не предусмотрено стандартными моделями. Для решения этой проблемы нужно уметь создавать свои виджеты, наследуя базовые виджеты и расширяя их функционал.
Например, в модели страницы мне нужно указать путь к шаблону, который используется для генерации редактируемой страницы, а список шаблонов извлекается путем сканирования каталога шаблонов текущего домена (многодоменная CMS) Для решения эта проблема, я наследую от wtforms .fields.SelectField новый класс SelectTemplateField, где я переопределяю конструктор, где я инициализирую параметр выбора для родительского класса
Это работает так: я объявляю новый класс в файле «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)
- Я заполняю список именами файлов из этого каталога
- Сортировать список
- Я удаляю элемент app_template из kwargs иначе базовый класс вылетает с ошибкой
- Добавить в отсортированный список доступных шаблонов в Kwargs
- Вызов конструктора базового класса
Затем этот виджет необходимо подключить к классу PageAdmin. Это делается путем добавления параметра form_extra_fields в класс PageAdmin следующим образом:
form_extra_fields = { 'template': SelectTemplateField(u'шаблон', app_template = os.path.join(app.root_path, app.template_folder)), }
Это определяет класс по умолчанию для свойства шаблона класса Page путем переопределения соответствующего виджета с его заголовком и инициализации свойства app_template (которое затем используется в переопределенном конструкторе класса).
Вот так просто и легко значительно расширить возможности генераторов форм в Flask