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

rhfm7lfc  于 2023-08-08  发布在  Go
关注(0)|答案(3)|浏览(138)

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

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.我不希望在消息前面显示*
1.我无法捕获用户键入的字符数,这是在默认消息中显示的。(it has 445)
如何打印Error: maximum length limit is 255 characters (it has 445).而不是* Error: maximum length limit is 255 characters.

qxsslcnc

qxsslcnc1#

我不希望在消息前面显示 *
你最后得出结论的问题(在评论中)是在

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返回true时才有效。你可以找到更多的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
                )

1mrurvl1

1mrurvl12#

你可以在表单中使用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

whitzsjs

whitzsjs3#

你问这个问题已经两年半了...但我已经找到了一个更好的解决方案,所以我写在这里的任何人谁访问这个问题在未来!让我解释一下
我可以通过在基于forms.Form的类中编辑clean函数来实现。

from django import forms

class myForm(forms.Form):
    text_field = forms.CharField(
        min_length=20,
        error_messages={'min_length': 'Minimum length is 20 but you entered {}!'}
    )

    def clean(self):
        super().clean()

        text = self.errors.get('text_field', None)

        if text:
            for i, x in enumerate(text):
                if x == self.fields['text_field'].error_messages['min_length']:
                    self.errors['text_field'][i] = x.format(len(self.data[f'{self.prefix}-text_field']))

字符串
同样对于forms.ModelForm对象,我们可以这样做:

from django import forms
from django.db import models

class myModel(models.Model):
    title = models.CharField(max_length=300)
    text = models.TextField()

class myModelForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.fields['text'] = forms.CharField(
            min_length=20,
            error_messages={'min_length':'Minimum length is 20 but you entered {}!'}
        )

    class Meta:
        model = myModel
        fields = ('title',)

    def _post_clean(self):
        super()._post_clean()

        text = self.errors.get('text', None)

        if text:
            for i, x in enumerate(text):
                if x == self.fields['text'].error_messages['min_length']:
                    self.errors['text'][i] = x.format(len(self.data[f'{self.prefix}-text']))

_post_clean是clean process完成后运行的函数,forms.Form对象没有这样的方法

我已经测试过了,它们工作得很好。

注意事项

对于forms.ModelForm对象,请确保在__init__函数中创建自定义字段,在模型中使用验证器将无法工作!
同样通过创建自定义字段,您在Meta类中为目标字段定义的所有内容都将被忽略,您必须在__init__函数中定义它们

相关问题