Disabled field is considered for validation in WTForms and Flask

后端 未结 4 779
别跟我提以往
别跟我提以往 2021-02-01 08:38

I have some fields in page disabled as for example:(using jinja2 templating system)



{{ form.na
4条回答
  •  余生分开走
    2021-02-01 09:12

    1. Create a custom validator
    from wtforms.validators import Optional
    class DisabledValidator(Optional):
        """
        do nothing
        """
        pass
    
    1. Let's create a custom rule basing on the form.rule
    from flask_admin.form.rules import Field
    class EasyCustomFieldRule(Field):
        def __init__(self, field_name, render_field='lib.render_field', field_args={}):
            super(self.__class__, self).__init__(field_name, render_field)
            self.extra_field_args = field_args
    
        def __call__(self, form, form_opts=None, field_args={}):
            field = getattr(form, self.field_name)
            if self.extra_field_args.get('disabled'):
                field.validators.append(DisabledValidator())
    
            field_args.update(self.extra_field_args)
            return super(self.__class__, self).__call__(form, form_opts, field_args)
    
    1. Override write some functions of wtforms.form
    from wtforms.form import Form
    from wtforms.compat import iteritems
    class BaseForm(Form):
        """
        重写部分方法,以适应disabled的Field
        """
    
        def validate(self):
            """
            Validates the form by calling `validate` on each field, passing any
            extra `Form.validate_` validators to the field validator.
            """
            extra = {}
            for name in self._fields:
                inline = getattr(self.__class__, 'validate_%s' % name, None)
                if inline is not None:
                    extra[name] = [inline]
    
            return self.validate_(extra)
    
        def validate_(self, extra_validators=None):
            self._errors = None
            success = True
            for name, field in iteritems(self._fields):
                is_disabled = False
                for v in field.validators:
                    if isinstance(v, DisabledValidator):
                        field.flags.disabled = True
                        is_disabled = True
                        break
                if is_disabled:
                    continue
    
                if extra_validators is not None and name in extra_validators:
                    extra = extra_validators[name]
                else:
                    extra = tuple()
                if not field.validate(self, extra):
                    success = False
            return success
    
        def populate_obj(self, obj):
            for name, field in self._fields.items():
                if not field.flags.disabled:
                    field.populate_obj(obj, name)
    
    1. set the form_base_class in your ModelView, and set the form_edit_rules or the form_create_rules with EasyCustomFieldRule
    from flask_admin.contrib.sqla import ModelView
    class MyTestModelView(ModelView):
        ...
        form_base_class = BaseForm
        ...
    
        form_edit_rules = (
            EasyCustomFieldRule('column0', field_args={'disabled': True}),
            'column1', 'column2'
        )
    
    1. Just testing...

提交回复
热议问题