Автоматическая установка атрибута id HTML элемента формы в flask -wtforms - PullRequest
0 голосов
/ 10 июля 2020

Есть ли способ автоматически сопоставить id самого элемента ввода формы с именем формы и именем переменной поля? т.е. для поля bar в экземпляре FooForm id будет foo-form--bar.

В настоящее время я использую этот подход для достижения этой цели, но он немного громоздкий:

from flask_wtf import FlaskForm
import wtforms as wtf

class FooForm(FlaskForm):
    FORM_NAME = 'foo-form'
    bar =  wtf.StringField('Bar', render_kw={'id': f'{FORM_NAME}--bar'})

1 Ответ

1 голос
/ 19 июля 2020

Я думаю, что создание подклассов усложняет ситуацию, поскольку подкласс содержит только одну или две строки. Вы можете сделать следующее:

def class_id(s):
    """Convert input string from PascalCase to kebab-case"""
    import re
    return re.sub(r'(?<!^)(?=[A-Z])', '-', s).lower() + '-'

class MyClass(object):
    form_name = class_id(__qualname__)
    print(f"{form_name}attribute")

class OtherClass(object):
    form_name = class_id(__qualname__)
    print(f"{form_name}attribute")

>>> MyClass()
>>> OtherClass()
my-class-attribute
other-class-attribute

edit: извините, полностью пропустил часть об автоматическом id c, тогда потребуется подклассификация, простой подход будет:

def AdjStringField(form_name, **kwargs):
    name = kwargs.get('name', 'Bar')
    return wtf.StringField(name, render_kw={
        'id': f'{}{}'.format(form_name, name.lower(),
        **kwargs.get('render_kw', {})})

class FooForm(FlaskForm):
    form_name = class_id(__qualname__)
    bar = AdjStringField(form_name)
    pipe = AdjStringField(form_name, name='Pipe', render_kw={'foo': 'bar'})

Вы можете перегрузить это для любого типа поля ввода, если вы указали его как в объекте аргумента:

def AdjField(Field, form_name, **kwargs):
    name = kwargs.get('name', 'Bar')
    return Field(name, render_kw={
        'id': f'{}{}'.format(form_name, name.lower(),
        **kwargs.get('render_kw', {})})

>>> AdjField(wtf.StringField, 'form-name')
>>> AdjField(wtf.InputBox, 'other-name', name='Pipe', render_kw={'foo': 'bar'})
...