在验证FormField的不同现场清单验证表单时,如何处理错误消息?

发布于 2025-02-01 09:15:16 字数 1802 浏览 4 评论 0原文

我有一个包含(在其他字段)的表格2个现场清单。每个现场清单都是FormFields的列表。在每个现场列表中,表单均代表项目。一个现场清单是针对预算带走的项目,另一个列表是针对将成为该预算的项目的项目。这是一种动态形式;可以有任意数量的交易或分配。整体形式中将有很多验证,但是我无法工作的一个简单案例是确保在表单中没有显示两次项目(也就是说,在这两个列表中,项目ID必须是唯一的)。我可以对此进行测试并认识到这种情况何时发生,但是我很难将错误消息与有问题的项目ID关联。

我的表单类的简化版本是:

class AllocationForm(Form):
    project_id(StringField, label='Project ID')
    ... details about amount being allocated here

class DeallocationForm(Form):
    project_id(StringField, label='Project ID')
    ...details about amount being deallocated here

class RequestForm(FlaskForm):

    def validate(self):

        project_id_seen = {}
        project_list = [a for a in self.allocations] + [d for d in self.deallocations]

        for formfield in project_list:
            if project_id_seen.get(formfield.data.get('project_id')) is None:
                project_id_seen[formfield.data.get('project_id')] = 1
            else:
                # *** Here's where I'm having an issue ***
                somethingsomethingsomething['project_id'] = 'A project ID cannot appear more than once in a request'
                return False

        # other form validations happen here
        if not FlaskForm.validate(self):
            return False

    allocations = FieldList(FormField(AllocationForm))
    deallocations = FieldList(FormField(DeallocationForm))

如您所见,我正在覆盖requestform's validate方法。在其他条款中我返回false的位置,我想将错误消息与相关项目ID相关联,以便在重新渲染表单时可以显示它,但是我有难以访问子图中的特定project_id字段。有什么想法吗?

编辑:在我看来,另一种方法可能是将验证器放在Allocationformdreadlocationform类中的项目ID字段上,而不是request> request uncesport。这是一种更可行的方法吗?将错误消息与字段相关联会更容易,但是alcoctform中的验证器将如何访问Deallocationform中的项目ID ,反之亦然?

I have a form that contains (among other fields) 2 FieldLists. Each FieldList is a list of FormFields. In each FieldList, the forms all represent projects. One fieldlist is for projects having budget taken away, and the other list is for projects that will be the recipients of that budget. This is a dynamic form; there can be an arbitrary number of deallocations or allocations. There will be a lot of validations in the overall form, but a simple case that I cannot get working is making sure no project appears twice in the form (that is to say that across both lists, project IDs must be unique). I can test for this and recognize when this situation occurs, but I am having trouble associating error messages with the offending project IDs.

A simplified version of my form classes is:

class AllocationForm(Form):
    project_id(StringField, label='Project ID')
    ... details about amount being allocated here

class DeallocationForm(Form):
    project_id(StringField, label='Project ID')
    ...details about amount being deallocated here

class RequestForm(FlaskForm):

    def validate(self):

        project_id_seen = {}
        project_list = [a for a in self.allocations] + [d for d in self.deallocations]

        for formfield in project_list:
            if project_id_seen.get(formfield.data.get('project_id')) is None:
                project_id_seen[formfield.data.get('project_id')] = 1
            else:
                # *** Here's where I'm having an issue ***
                somethingsomethingsomething['project_id'] = 'A project ID cannot appear more than once in a request'
                return False

        # other form validations happen here
        if not FlaskForm.validate(self):
            return False

    allocations = FieldList(FormField(AllocationForm))
    deallocations = FieldList(FormField(DeallocationForm))

As you can see, I'm overriding RequestForm's validate method. Where I return False in the else clause, I'd like to associate an error message with the project ID in question so that I can display it when the form is re-rendered, but I'm having difficulty accessing the specific project_id field in the subform. Any ideas?

EDIT: It occurs to me that another approach might be to put validators on the project ID fields in the AllocationForm and DeallocationForm classes instead of RequestForm. Is this a more feasible approach? Associating the error message with the field would be easier, but how would the validator in AllocationForm access the project IDs in DeallocationForm and vice versa?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

迷迭香的记忆 2025-02-08 09:15:17

您使用验证的方法对我来说很有意义,我认为您即将达到目标。
为了能够将错误消息分配给字段,您可以暂时存储必要的字段,然后在各个字段的错误消息元组中添加一个条目,只要有必要。

from collections import defaultdict

class AllocationForm(Form):
    project_id = StringField('Project ID')
    # ...

class DeallocationForm(Form):
    project_id = StringField('Project ID')
    # ...

class RequestForm(FlaskForm):
    allocations = FieldList(FormField(AllocationForm))
    deallocations = FieldList(FormField(DeallocationForm))

    def validate(self):
        data_fields = defaultdict(list)
        for field in (self.allocations, self.deallocations):
            for form in field:
                if form.project_id.data:
                    data_fields[form.project_id.data].append(form.project_id)

        success = True
        for data,fields in data_fields.items():
            if len(fields) > 1:
                for field in fields:
                    msg = 'A project ID cannot appear more than once in a request'
                    field.errors += (msg,)
                success = False

        return success and super().validate()

Your approach of using validate makes sense to me and I think you are close to reaching your goal.
In order to be able to assign the error message to a field, you can temporarily store the necessary fields and then add an entry to the tuple of error messages of the respective field for as long as it is necessary.

from collections import defaultdict

class AllocationForm(Form):
    project_id = StringField('Project ID')
    # ...

class DeallocationForm(Form):
    project_id = StringField('Project ID')
    # ...

class RequestForm(FlaskForm):
    allocations = FieldList(FormField(AllocationForm))
    deallocations = FieldList(FormField(DeallocationForm))

    def validate(self):
        data_fields = defaultdict(list)
        for field in (self.allocations, self.deallocations):
            for form in field:
                if form.project_id.data:
                    data_fields[form.project_id.data].append(form.project_id)

        success = True
        for data,fields in data_fields.items():
            if len(fields) > 1:
                for field in fields:
                    msg = 'A project ID cannot appear more than once in a request'
                    field.errors += (msg,)
                success = False

        return success and super().validate()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文