Часто требуется на формах 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
                        
                                    
                                
Комментариев 0