如何更改 Django 表单显示的默认错误消息

Posted

技术标签:

【中文标题】如何更改 Django 表单显示的默认错误消息【英文标题】:How to change the default error messages displayed by Django forms 【发布时间】:2021-04-15 04:14:03 【问题描述】:

我在 Django 中创建了一个表单,它有一个 max_length=255 的字符域,如下所示:

task = models.CharField(max_length= 255)

现在我想让用户知道他输入了多少个字符,如果他超过了 255 个字符的限制,所以我做了以下操作

if form.is_valid():
    #some code
else:
    messages.info(request,(form.errors.get("task").as_text()))

现在假设如果我在表单字段中输入 445 个字符并提交,那么 默认情况下我会收到以下错误消息:

* Ensure this value has at most 255 characters (it has 445).

但是,我想将此消息更改为:

Error: maximum length limit is 255 characters (it has 445).

所以我尝试了以下方法:

class ListForm(ModelForm):
    class Meta:
        model = ListModel
        fields = ["task", "status"]

        error_messages = 
            'task': 
                'max_length': ("Error: maximum length limit is 255 characters"),
                
            ,
        

现在消息已更改为:

* Error: maximum length limit is 255 characters.

我的问题:

    我不希望在消息前面显示* 我无法捕获用户输入的字符数,这些字符显示在默认消息中,即(it has 445)

我可以做些什么来打印 Error: maximum length limit is 255 characters (it has 445). 而不是 * Error: maximum length limit is 255 characters.?

【问题讨论】:

您能给我们看一下表格的html 吗?我很确定星号 * 是 HTML <li> 我已经使用Django form class 来生成表单,所以我没有专门为表单定义任何HTML。 当然,但问题是您如何访问模板中的messages.info。对我来说,messages.info 不包含星号,如果我在没有任何 HTML 标记的情况下访问它。标准的django.forms.Form 类不会为messages.info 呈现任何HTML,您必须自己访问它。 好的,现在我明白了,要访问 HTML 中的消息,我正在执行以下操作:% if messages %% for message in messages % <p> message </p> % endfor %% endif %,所以我认为我的 HTML 中没有使用任何 类跨度> 奇怪。也许您可以尝试输入messages.info(request, "some test string") 并告诉我们是否仍然存在相同的问题。您也可以尝试print(form.errors.get("task").as_text()) 看看那里是否有星号或者是否是 HTML 问题。括号也是多余的 【参考方案1】:

我不希望显示在消息前面的 *

您最终得出结论的问题(在 cmets 中)在于

form.errors.get("task").as_text()

这会向客户端发送一个<ul> HTML 元素,而不是纯文本。因此,您可以做些什么来解决这个问题和其他问题,只需检查max_length 是否可以在form.errors 中找到并使用您自己的string。在调用form.is_valid 后,您的视图中应该出现以下内容

# After this point form.is_valid() has been called
if "max_length" in form.errors:
    task = request.POST.get("task") # Get the text that was entered in `task`
    length_of_task = len(task) 
    # Simply send your own message
    messages.info(request, f"Error: maximum length limit is 255 characters (it has length_of_task).")

注意几点

使用request.POST.get访问数据

@SaeX 指出可以使用self.cleaned_data.get 获取POST 请求中发送的数据。虽然这是真的,只有在 form.is_valid 返回真时才有效。你可以了解更多here。

如果我想捕获多个错误并使用字典怎么办

您仍然可以使用字典,但对于值,您必须使用函数。类似于以下内容

def handle_max_length(data):
    datalen = len(data) > 255 # Do your stuff
    
def handle_some_other_error(data):
    pass 

errors = 
    'max_length' : handle_max_length,
    'some_other_error': handle_some_other_error


def myView(request):
    # ... code
    form = MyForm()
    if not form.is_valid():
        for field in form.errors:
            field_value = request.POST.get(field)
            for error in field:
                messages.info(
                    request, errors.get(error)(field_value) # Getting the function and calling it with the data
                )

【讨论】:

好的,所以我打印了form.errors,它是这样的:<ul class="errorlist"><li>item<ul class="errorlist"><li>Ensure this value has at most 255 characters (it has 445).</li></ul></li></ul>,所以max_length 不存在于form.errors 中,因此条件if "max_length" in form.errors 将始终返回False。但是您的解决方案仍然解决了我的问题,因为当 form.is_valid() 为 False 我们不再需要 if "max_length" in form.errors 时,我们可以直接执行 if length_of_task > 255 并打印消息。非常感谢您的帮助。 访问request.POST 并进行自己的验证,大多数时候是更好的选择。请注意,在一些边缘情况下,当您可能发送文件时,您只能访问来自request.POST 的数据一次(文件数据)。否则一切正常。【参考方案2】:

您可以在表单中使用clean_<fieldname>(),例如:

def clean_task(self):
    task = self.cleaned_data.get("task")

    if len(task) > 255:
        raise ValidationError("Error: maximum length limit is 255 characters (it has %s.") % len(task)

    return task

见https://docs.djangoproject.com/en/3.1/ref/forms/validation/#cleaning-a-specific-field-attribute

【讨论】:

if len(task) > 255: 在表单中添加函数后,是否需要在views.py 中的某处调用它,因为添加后我得到的是默认消息* Ensure this value has at most 255 characters (it has 445).,而不是自定义消息 这仅在form.is_valid()返回true时有效。

以上是关于如何更改 Django 表单显示的默认错误消息的主要内容,如果未能解决你的问题,请参考以下文章

更改 django 在显示表单错误消息时使用的字段名称

[oldboy-django][2深入django]老师管理 -- form表单如何生成多选框标签,多选框的默认值显示,以及多选框数据插入到数据库,多选框数据更改到数据库

如何删除所需属性的 HTML5 表单验证默认错误消息 [重复]

django 表单错误。得到没有任何 html 标签的错误

如何在 Django Admin 中更改 OneToOne 模型字段默认消息?

Django rest框架:如何全局更改错误响应格式