【问题标题】:How to change the default error messages displayed by Django forms如何更改 Django 表单显示的默认错误消息
【发布时间】: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.

我的问题:

  1. 我不希望在消息前面显示*
  2. 我无法捕获用户输入的字符数,这些字符显示在默认消息中,即(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 问题。括号也是多余的
  • 标签: python django django-models django-forms django-validation


    【解决方案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时有效。
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签